From b373c866e74adb2ee5c27479b6fac75d9e6f76fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 24 Sep 2014 02:01:53 +0200 Subject: Merge openpgp-card lib into OpenKeychain, it was already depending on OK, no need to separate --- .../jcajce/NfcSyncPGPContentSignerBuilder.java | 144 +++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 OpenKeychain/src/main/java/org/spongycastle/openpgp/operator/jcajce/NfcSyncPGPContentSignerBuilder.java (limited to 'OpenKeychain/src/main/java/org/spongycastle/openpgp/operator/jcajce/NfcSyncPGPContentSignerBuilder.java') diff --git a/OpenKeychain/src/main/java/org/spongycastle/openpgp/operator/jcajce/NfcSyncPGPContentSignerBuilder.java b/OpenKeychain/src/main/java/org/spongycastle/openpgp/operator/jcajce/NfcSyncPGPContentSignerBuilder.java new file mode 100644 index 000000000..e0286ec15 --- /dev/null +++ b/OpenKeychain/src/main/java/org/spongycastle/openpgp/operator/jcajce/NfcSyncPGPContentSignerBuilder.java @@ -0,0 +1,144 @@ +/** + * Copyright (c) 2013-2014 Philipp Jakubeit, Signe Rüsch, Dominik Schürmann + * Copyright (c) 2000-2013 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) + * + * Licensed under the Bouncy Castle License (MIT license). See LICENSE file for details. + */ + +package org.spongycastle.openpgp.operator.jcajce; + +import org.spongycastle.openpgp.PGPException; +import org.spongycastle.openpgp.PGPPrivateKey; +import org.spongycastle.openpgp.operator.PGPContentSigner; +import org.spongycastle.openpgp.operator.PGPContentSignerBuilder; +import org.spongycastle.openpgp.operator.PGPDigestCalculator; + +import java.io.OutputStream; +import java.security.Provider; +import java.util.Date; + +/** + * This class is based on JcaPGPContentSignerBuilder. + * + * Instead of using a Signature object based on a privateKey, this class only calculates the digest + * of the output stream and gives the result back using a RuntimeException. + */ +public class NfcSyncPGPContentSignerBuilder + implements PGPContentSignerBuilder +{ + private JcaPGPDigestCalculatorProviderBuilder digestCalculatorProviderBuilder = new JcaPGPDigestCalculatorProviderBuilder(); + private int hashAlgorithm; + private int keyAlgorithm; + private long keyID; + + private byte[] signedHash; + private Date creationTimestamp; + + public static class NfcInteractionNeeded extends RuntimeException + { + public byte[] hashToSign; + public Date creationTimestamp; + public int hashAlgo; + + public NfcInteractionNeeded(byte[] hashToSign, int hashAlgo, Date creationTimestamp) + { + super("NFC interaction required!"); + this.hashToSign = hashToSign; + this.hashAlgo = hashAlgo; + this.creationTimestamp = creationTimestamp; + } + } + + public NfcSyncPGPContentSignerBuilder(int keyAlgorithm, int hashAlgorithm, long keyID, byte[] signedHash, Date creationTimestamp) + { + this.keyAlgorithm = keyAlgorithm; + this.hashAlgorithm = hashAlgorithm; + this.keyID = keyID; + this.signedHash = signedHash; + this.creationTimestamp = creationTimestamp; + } + + public NfcSyncPGPContentSignerBuilder setProvider(Provider provider) + { + digestCalculatorProviderBuilder.setProvider(provider); + + return this; + } + + public NfcSyncPGPContentSignerBuilder setProvider(String providerName) + { + digestCalculatorProviderBuilder.setProvider(providerName); + + return this; + } + + public NfcSyncPGPContentSignerBuilder setDigestProvider(Provider provider) + { + digestCalculatorProviderBuilder.setProvider(provider); + + return this; + } + + public NfcSyncPGPContentSignerBuilder setDigestProvider(String providerName) + { + digestCalculatorProviderBuilder.setProvider(providerName); + + return this; + } + + public PGPContentSigner build(final int signatureType, PGPPrivateKey privateKey) + throws PGPException { + // NOTE: privateKey is null in this case! + return build(signatureType, keyID); + } + + public PGPContentSigner build(final int signatureType, final long keyID) + throws PGPException + { + final PGPDigestCalculator digestCalculator = digestCalculatorProviderBuilder.build().get(hashAlgorithm); + + return new PGPContentSigner() + { + public int getType() + { + return signatureType; + } + + public int getHashAlgorithm() + { + return hashAlgorithm; + } + + public int getKeyAlgorithm() + { + return keyAlgorithm; + } + + public long getKeyID() + { + return keyID; + } + + public OutputStream getOutputStream() + { + return digestCalculator.getOutputStream(); + } + + public byte[] getSignature() { + if (signedHash != null) { + // we already have the signed hash from a previous execution, return this! + return signedHash; + } else { + // catch this when signatureGenerator.generate() is executed and divert digest to card, + // when doing the operation again reuse creationTimestamp (this will be hashed) + throw new NfcInteractionNeeded(digestCalculator.getDigest(), getHashAlgorithm(), creationTimestamp); + } + } + + public byte[] getDigest() + { + return digestCalculator.getDigest(); + } + }; + } +} -- cgit v1.2.3