aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/NfcOperationsParcel.java
blob: b9ee9e6ca4111d2d3e0cd25fcb7eb8ad461f3574 (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
136
package org.sufficientlysecure.keychain.service.input;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;

import android.os.Parcel;
import android.os.Parcelable;


public class NfcOperationsParcel implements Parcelable {

    public enum NfcOperationType {
        NFC_SIGN, NFC_DECRYPT
    }

    public Date mSignatureTime;
    public final NfcOperationType mType;
    public final byte[][] mInputHashes;
    public final int[] mSignAlgos;

    private NfcOperationsParcel(NfcOperationType type, byte[][] inputHashes,
            int[] signAlgos, Date signatureTime) {
        mType = type;
        mInputHashes = inputHashes;
        mSignAlgos = signAlgos;
        mSignatureTime = signatureTime;
    }

    public NfcOperationsParcel(Parcel source) {
        mType = NfcOperationType.values()[source.readInt()];

        {
            int count = source.readInt();
            mInputHashes = new byte[count][];
            mSignAlgos = new int[count];
            for (int i = 0; i < count; i++) {
                mInputHashes[i] = source.createByteArray();
                mSignAlgos[i] = source.readInt();
            }
        }

        mSignatureTime = source.readInt() != 0 ? new Date(source.readLong()) : null;

    }

    public static NfcOperationsParcel createNfcSignOperation(
            byte[] inputHash, int signAlgo, Date signatureTime) {
        return new NfcOperationsParcel(NfcOperationType.NFC_SIGN,
                new byte[][] { inputHash }, new int[] { signAlgo }, signatureTime);
    }

    public static NfcOperationsParcel createNfcDecryptOperation(byte[] inputHash) {
        return new NfcOperationsParcel(NfcOperationType.NFC_DECRYPT,
                new byte[][] { inputHash }, null, null);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mType.ordinal());
        dest.writeInt(mInputHashes.length);
        for (int i = 0; i < mInputHashes.length; i++) {
            dest.writeByteArray(mInputHashes[i]);
            dest.writeInt(mSignAlgos[i]);
        }
        if (mSignatureTime != null) {
            dest.writeInt(1);
            dest.writeLong(mSignatureTime.getTime());
        } else {
            dest.writeInt(0);
        }

    }

    public static final Creator<NfcOperationsParcel> CREATOR = new Creator<NfcOperationsParcel>() {
        public NfcOperationsParcel createFromParcel(final Parcel source) {
            return new NfcOperationsParcel(source);
        }

        public NfcOperationsParcel[] newArray(final int size) {
            return new NfcOperationsParcel[size];
        }
    };

    public static class NfcSignOperationsBuilder {
        Date mSignatureTime;
        ArrayList<Integer> mSignAlgos = new ArrayList<>();
        ArrayList<byte[]> mInputHashes = new ArrayList<>();

        public NfcSignOperationsBuilder(Date signatureTime) {
            mSignatureTime = signatureTime;
        }

        public NfcOperationsParcel build() {
            byte[][] inputHashes = new byte[mInputHashes.size()][];
            mInputHashes.toArray(inputHashes);
            int[] signAlgos = new int[mSignAlgos.size()];
            for (int i = 0; i < mSignAlgos.size(); i++) {
                signAlgos[i] = mSignAlgos.get(i);
            }

            return new NfcOperationsParcel(NfcOperationType.NFC_SIGN,
                    inputHashes, signAlgos, mSignatureTime);
        }

        public void addHash(byte[] hash, int algo) {
            mInputHashes.add(hash);
            mSignAlgos.add(algo);
        }

        public void addAll(NfcOperationsParcel input) {
            if (!mSignatureTime.equals(input.mSignatureTime)) {
                throw new AssertionError("input times must match, this is a programming error!");
            }
            if (input.mType != NfcOperationType.NFC_SIGN) {
                throw new AssertionError("operation types must match, this is a progrmming error!");
            }

            Collections.addAll(mInputHashes, input.mInputHashes);
            for (int signAlgo : input.mSignAlgos) {
                mSignAlgos.add(signAlgo);
            }
        }

        public boolean isEmpty() {
            return mInputHashes.isEmpty();
        }

    }

}