001/**
002 *
003 * Copyright 2018 Paul Schaub.
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.jivesoftware.smackx.ox.element;
018
019import java.nio.charset.Charset;
020import java.util.Date;
021
022import org.jivesoftware.smack.packet.ExtensionElement;
023import org.jivesoftware.smack.packet.NamedElement;
024import org.jivesoftware.smack.util.Objects;
025import org.jivesoftware.smack.util.XmlStringBuilder;
026
027/**
028 * Class representing a pubkey element which is used to transport OpenPGP public keys.
029 *
030 * @see <a href="https://xmpp.org/extensions/xep-0373.html#announcing-pubkey">
031 *     XEP-0373: ยง4.1 The OpenPGP Public-Key Data Node</a>
032 */
033public class PubkeyElement implements ExtensionElement {
034
035    public static final String NAMESPACE = OpenPgpElement.NAMESPACE;
036    public static final String ELEMENT = "pubkey";
037    public static final String ATTR_DATE = "date";
038
039    private final PubkeyDataElement dataElement;
040    private final Date date;
041
042    public PubkeyElement(PubkeyDataElement dataElement, Date date) {
043        this.dataElement = Objects.requireNonNull(dataElement);
044        this.date = date;
045    }
046
047    /**
048     * Return the &lt;data&gt; element containing the base64 encoded public key.
049     *
050     * @return data element
051     */
052    public PubkeyDataElement getDataElement() {
053        return dataElement;
054    }
055
056    /**
057     * Date on which the key was last modified.
058     *
059     * @return last modification date
060     */
061    public Date getDate() {
062        return date;
063    }
064
065    @Override
066    public String getNamespace() {
067        return NAMESPACE;
068    }
069
070    @Override
071    public String getElementName() {
072        return ELEMENT;
073    }
074
075    @Override
076    public XmlStringBuilder toXML(String enclosingNamespace) {
077        XmlStringBuilder xml = new XmlStringBuilder(this)
078                .optAttribute(ATTR_DATE, date)
079                .rightAngleBracket()
080                .element(getDataElement())
081                .closeElement(this);
082        return xml;
083    }
084
085    /**
086     * Element that contains the base64 encoded public key.
087     */
088    public static class PubkeyDataElement implements NamedElement {
089
090        public static final String ELEMENT = "data";
091
092        private final byte[] b64Data;
093
094        public PubkeyDataElement(byte[] b64Data) {
095            this.b64Data = Objects.requireNonNull(b64Data);
096        }
097
098        /**
099         * Base64 encoded public key.
100         *
101         * @return public key bytes.
102         */
103        public byte[] getB64Data() {
104            return b64Data;
105        }
106
107        @Override
108        public String getElementName() {
109            return ELEMENT;
110        }
111
112        @Override
113        public XmlStringBuilder toXML(String enclosingNamespace) {
114            XmlStringBuilder xml = new XmlStringBuilder(this)
115                    .rightAngleBracket()
116                    .append(new String(b64Data, Charset.forName("UTF-8")))
117                    .closeElement(this);
118            return xml;
119        }
120    }
121}