aboutsummaryrefslogtreecommitdiffstats
path: root/xcode/Samples/FrameworkSample
diff options
context:
space:
mode:
Diffstat (limited to 'xcode/Samples/FrameworkSample')
0 files changed, 0 insertions, 0 deletions
id='n11' href='#n11'>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 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
package org.sufficientlysecure.keychain.pgp;

import org.spongycastle.bcpg.SignatureSubpacket;
import org.spongycastle.bcpg.SignatureSubpacketTags;
import org.spongycastle.bcpg.sig.RevocationReason;
import org.spongycastle.openpgp.PGPException;
import org.spongycastle.openpgp.PGPObjectFactory;
import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.PGPSignatureList;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.util.Log;

import java.io.IOException;
import java.security.SignatureException;
import java.util.Date;

/** OpenKeychain wrapper around PGPSignature objects.
 *
 * This is a mostly simple wrapper around a single bouncycastle PGPSignature
 * object. It exposes high level getters for all relevant information, methods
 * for verification of various signatures (uid binding, subkey binding, generic
 * bytes), and a static method for construction from bytes.
 *
 */
public class WrappedSignature {

    public static final int DEFAULT_CERTIFICATION = PGPSignature.DEFAULT_CERTIFICATION;
    public static final int NO_CERTIFICATION = PGPSignature.NO_CERTIFICATION;
    public static final int CASUAL_CERTIFICATION = PGPSignature.CASUAL_CERTIFICATION;
    public static final int POSITIVE_CERTIFICATION = PGPSignature.POSITIVE_CERTIFICATION;
    public static final int CERTIFICATION_REVOCATION = PGPSignature.CERTIFICATION_REVOCATION;

    final PGPSignature mSig;

    WrappedSignature(PGPSignature sig) {
        mSig = sig;
    }

    public long getKeyId() {
        return mSig.getKeyID();
    }

    public int getSignatureType() {
        return mSig.getSignatureType();
    }

    public int getKeyAlgorithm() {
        return mSig.getKeyAlgorithm();
    }

    public Date getCreationTime() {
        return mSig.getCreationTime();
    }

    public byte[] getEncoded() throws IOException {
        return mSig.getEncoded();
    }

    public boolean isRevocation() {
        return mSig.getHashedSubPackets().hasSubpacket(SignatureSubpacketTags.REVOCATION_REASON);
    }

    public boolean isPrimaryUserId() {
        return mSig.getHashedSubPackets().isPrimaryUserID();
    }

    public String getRevocationReason() throws PgpGeneralException {
        if(!isRevocation()) {
            throw new PgpGeneralException("Not a revocation signature.");
        }
        SignatureSubpacket p = mSig.getHashedSubPackets().getSubpacket(
                SignatureSubpacketTags.REVOCATION_REASON);
        // For some reason, this is missing in SignatureSubpacketInputStream:146
        if (!(p instanceof RevocationReason)) {
            p = new RevocationReason(false, p.getData());
        }
        return ((RevocationReason) p).getRevocationDescription();
    }

    public void init(WrappedPublicKey key) throws PgpGeneralException {
        init(key.getPublicKey());
    }

    public void init(UncachedPublicKey key) throws PgpGeneralException {
        init(key.getPublicKey());
    }

    void init(PGPPublicKey key) throws PgpGeneralException {
        try {
            JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
                    new JcaPGPContentVerifierBuilderProvider()
                            .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
            mSig.init(contentVerifierBuilderProvider, key);
        } catch(PGPException e) {
            throw new PgpGeneralException(e);
        }
    }

    public void update(byte[] data, int offset, int length) throws PgpGeneralException {
        try {
            mSig.update(data, offset, length);
        } catch(SignatureException e) {
            throw new PgpGeneralException(e);
        }
    }

    public void update(byte data) throws PgpGeneralException {
        try {
            mSig.update(data);
        } catch(SignatureException e) {
            throw new PgpGeneralException(e);
        }
    }

    public boolean verify() throws PgpGeneralException {
        try {
            return mSig.verify();
        } catch(SignatureException e) {
            throw new PgpGeneralException(e);
        } catch(PGPException e) {
            throw new PgpGeneralException(e);
        }
    }

    boolean verifySignature(PGPPublicKey key) throws PgpGeneralException {
        try {
            return mSig.verifyCertification(key);
        } catch (SignatureException e) {
            throw new PgpGeneralException("Sign!", e);
        } catch (PGPException e) {
            throw new PgpGeneralException("Error!", e);
        }
    }

    boolean verifySignature(PGPPublicKey masterKey, PGPPublicKey subKey) throws PgpGeneralException {
        try {
            return mSig.verifyCertification(masterKey, subKey);
        } catch (SignatureException e) {
            throw new PgpGeneralException("Sign!", e);
        } catch (PGPException e) {
            throw new PgpGeneralException("Error!", e);
        }
    }

    boolean verifySignature(PGPPublicKey key, String uid) throws PgpGeneralException {
        try {
            return mSig.verifyCertification(uid, key);
        } catch (SignatureException e) {
            throw new PgpGeneralException("Error!", e);
        } catch (PGPException e) {
            throw new PgpGeneralException("Error!", e);
        }
    }

    public boolean verifySignature(UncachedPublicKey key, String uid) throws PgpGeneralException {
        return verifySignature(key.getPublicKey(), uid);
    }
    public boolean verifySignature(WrappedPublicKey key, String uid) throws PgpGeneralException {
        return verifySignature(key.getPublicKey(), uid);
    }

    public static WrappedSignature fromBytes(byte[] data) {
        PGPObjectFactory factory = new PGPObjectFactory(data);
        PGPSignatureList signatures = null;
        try {
            if ((signatures = (PGPSignatureList) factory.nextObject()) == null || signatures.isEmpty()) {
                Log.e(Constants.TAG, "No signatures given!");
                return null;
            }
        } catch (IOException e) {
            Log.e(Constants.TAG, "Error while converting to PGPSignature!", e);
            return null;
        }

        return new WrappedSignature(signatures.get(0));
    }

    public boolean isLocal() {
        if (!mSig.hasSubpackets()
                || !mSig.getHashedSubPackets().hasSubpacket(SignatureSubpacketTags.EXPORTABLE)) {
            return false;
        }
        SignatureSubpacket p = mSig.getHashedSubPackets().getSubpacket(SignatureSubpacketTags.EXPORTABLE);
        return p.getData()[0] == 0;
    }
}