aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedUserAttribute.java
blob: e1f90334530a32bc815efd42a67d285b6dfca5e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
 * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.sufficientlysecure.keychain.pgp;

import org.bouncycastle.bcpg.BCPGInputStream;
import org.bouncycastle.bcpg.BCPGOutputStream;
import org.bouncycastle.bcpg.Packet;
import org.bouncycastle.bcpg.UserAttributePacket;
import org.bouncycastle.bcpg.UserAttributeSubpacket;
import org.bouncycastle.bcpg.UserAttributeSubpacketInputStream;
import org.bouncycastle.bcpg.UserAttributeSubpacketTags;
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.ArrayList;

public class WrappedUserAttribute implements Serializable {

    public static final int UAT_NONE = 0;
    public static final int UAT_IMAGE = UserAttributeSubpacketTags.IMAGE_ATTRIBUTE;
    public static final int UAT_URI_ATTRIBUTE = 101;

    private PGPUserAttributeSubpacketVector mVector;

    WrappedUserAttribute(PGPUserAttributeSubpacketVector vector) {
        mVector = vector;
    }

    PGPUserAttributeSubpacketVector getVector() {
        return mVector;
    }

    public int getType() {
        UserAttributeSubpacket[] subpackets = mVector.toSubpacketArray();
        if (subpackets.length > 0) {
            return subpackets[0].getType();
        }
        return 0;
    }

    public static WrappedUserAttribute fromSubpacket (int type, byte[] data) {
        UserAttributeSubpacket subpacket = new UserAttributeSubpacket(type, data);
        PGPUserAttributeSubpacketVector vector = new PGPUserAttributeSubpacketVector(
                new UserAttributeSubpacket[] { subpacket });

        return new WrappedUserAttribute(vector);

    }

    public byte[] getEncoded () throws IOException {
        UserAttributeSubpacket[] subpackets = mVector.toSubpacketArray();
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        for (UserAttributeSubpacket subpacket : subpackets) {
            subpacket.encode(out);
        }
        return out.toByteArray();
    }

    public static WrappedUserAttribute fromData (byte[] data) throws IOException {
        UserAttributeSubpacketInputStream in =
                new UserAttributeSubpacketInputStream(new ByteArrayInputStream(data));
        ArrayList<UserAttributeSubpacket> list = new ArrayList<>();
        while (in.available() > 0) {
            list.add(in.readPacket());
        }
        UserAttributeSubpacket[] result = new UserAttributeSubpacket[list.size()];
        list.toArray(result);
        return new WrappedUserAttribute(
                new PGPUserAttributeSubpacketVector(result));
    }

    /** Writes this object to an ObjectOutputStream. */
    private void writeObject(java.io.ObjectOutputStream out) throws IOException {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        BCPGOutputStream bcpg = new BCPGOutputStream(baos);
        bcpg.writePacket(new UserAttributePacket(mVector.toSubpacketArray()));
        out.writeObject(baos.toByteArray());

    }

    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {

        byte[] data = (byte[]) in.readObject();
        BCPGInputStream bcpg = new BCPGInputStream(new ByteArrayInputStream(data));
        Packet p = bcpg.readPacket();
        if ( ! UserAttributePacket.class.isInstance(p)) {
            throw new IOException("Could not decode UserAttributePacket!");
        }
        mVector = new PGPUserAttributeSubpacketVector(((UserAttributePacket) p).getSubpackets());

    }

    public byte[][] getSubpackets() {
        UserAttributeSubpacket[] subpackets = mVector.toSubpacketArray();
        byte[][] ret = new byte[subpackets.length][];
        for (int i = 0; i < subpackets.length; i++) {
            ret[i] = subpackets[i].getData();
        }
        return ret;
    }

    private void readObjectNoData() throws ObjectStreamException {
    }

    @SuppressWarnings("SimplifiableIfStatement")
    @Override
    public boolean equals(Object o) {
        if (!WrappedUserAttribute.class.isInstance(o)) {
            return false;
        }
        return mVector.equals(((WrappedUserAttribute) o).mVector);
    }

}