diff options
author | Sergio Giro <sgiro@google.com> | 2015-12-11 18:58:58 +0000 |
---|---|---|
committer | Sergio Giro <sgiro@google.com> | 2016-01-25 15:38:49 +0000 |
commit | 16f9ee464b68937f45d009d9c1b0eb9b544a8dee (patch) | |
tree | 61086f6673133c387b13b0e494e42973c6f4c0e8 /bcprov/src/main/java/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceCCA2KeyFactorySpi.java | |
parent | fcfe48e7cf461bf4a6314802c0f31f292d87ab95 (diff) | |
download | android_external_bouncycastle-16f9ee464b68937f45d009d9c1b0eb9b544a8dee.tar.gz android_external_bouncycastle-16f9ee464b68937f45d009d9c1b0eb9b544a8dee.tar.bz2 android_external_bouncycastle-16f9ee464b68937f45d009d9c1b0eb9b544a8dee.zip |
bouncycastle: Android tree with upstream code for version 1.49
Android tree as of 08e455bd61ddaa02255383e85480b0d9cde6e954
Change-Id: I99dab80b49707f0fdefb67ccd1bcfe765363b5e5
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceCCA2KeyFactorySpi.java')
-rw-r--r-- | bcprov/src/main/java/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceCCA2KeyFactorySpi.java | 346 |
1 files changed, 346 insertions, 0 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceCCA2KeyFactorySpi.java b/bcprov/src/main/java/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceCCA2KeyFactorySpi.java new file mode 100644 index 0000000..c6ca7c2 --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/pqc/jcajce/provider/mceliece/McElieceCCA2KeyFactorySpi.java @@ -0,0 +1,346 @@ +package org.bouncycastle.pqc.jcajce.provider.mceliece; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactorySpi; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.pqc.asn1.McElieceCCA2PrivateKey; +import org.bouncycastle.pqc.asn1.McElieceCCA2PublicKey; +import org.bouncycastle.pqc.jcajce.spec.McElieceCCA2PrivateKeySpec; +import org.bouncycastle.pqc.jcajce.spec.McElieceCCA2PublicKeySpec; + +/** + * This class is used to translate between McEliece CCA2 keys and key + * specifications. + * + * @see BCMcElieceCCA2PrivateKey + * @see McElieceCCA2PrivateKeySpec + * @see BCMcElieceCCA2PublicKey + * @see McElieceCCA2PublicKeySpec + */ +public class McElieceCCA2KeyFactorySpi + extends KeyFactorySpi +{ + + /** + * The OID of the algorithm. + */ + public static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.2"; + + /** + * Converts, if possible, a key specification into a + * {@link BCMcElieceCCA2PublicKey}. Currently, the following key + * specifications are supported: {@link McElieceCCA2PublicKeySpec}, + * {@link X509EncodedKeySpec}. + * + * @param keySpec the key specification + * @return the McEliece CCA2 public key + * @throws InvalidKeySpecException if the key specification is not supported. + */ + public PublicKey generatePublic(KeySpec keySpec) + throws InvalidKeySpecException + { + if (keySpec instanceof McElieceCCA2PublicKeySpec) + { + return new BCMcElieceCCA2PublicKey( + (McElieceCCA2PublicKeySpec)keySpec); + } + else if (keySpec instanceof X509EncodedKeySpec) + { + // get the DER-encoded Key according to X.509 from the spec + byte[] encKey = ((X509EncodedKeySpec)keySpec).getEncoded(); + + // decode the SubjectPublicKeyInfo data structure to the pki object + SubjectPublicKeyInfo pki; + try + { + pki = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(encKey)); + } + catch (IOException e) + { + throw new InvalidKeySpecException(e.toString()); + } + + + try + { + // --- Build and return the actual key. + ASN1Primitive innerType = pki.parsePublicKey(); + ASN1Sequence publicKey = (ASN1Sequence)innerType; + + // decode oidString (but we don't need it right now) + String oidString = ((ASN1ObjectIdentifier)publicKey.getObjectAt(0)) + .toString(); + + // decode <n> + BigInteger bigN = ((ASN1Integer)publicKey.getObjectAt(1)).getValue(); + int n = bigN.intValue(); + + // decode <t> + BigInteger bigT = ((ASN1Integer)publicKey.getObjectAt(2)).getValue(); + int t = bigT.intValue(); + + // decode <matrixG> + byte[] matrixG = ((ASN1OctetString)publicKey.getObjectAt(3)).getOctets(); + + return new BCMcElieceCCA2PublicKey(new McElieceCCA2PublicKeySpec( + OID, n, t, matrixG)); + } + catch (IOException cce) + { + throw new InvalidKeySpecException( + "Unable to decode X509EncodedKeySpec: " + + cce.getMessage()); + } + } + + throw new InvalidKeySpecException("Unsupported key specification: " + + keySpec.getClass() + "."); + } + + /** + * Converts, if possible, a key specification into a + * {@link BCMcElieceCCA2PrivateKey}. Currently, the following key + * specifications are supported: {@link McElieceCCA2PrivateKeySpec}, + * {@link PKCS8EncodedKeySpec}. + * + * @param keySpec the key specification + * @return the McEliece CCA2 private key + * @throws InvalidKeySpecException if the KeySpec is not supported. + */ + public PrivateKey generatePrivate(KeySpec keySpec) + throws InvalidKeySpecException + { + if (keySpec instanceof McElieceCCA2PrivateKeySpec) + { + return new BCMcElieceCCA2PrivateKey( + (McElieceCCA2PrivateKeySpec)keySpec); + } + else if (keySpec instanceof PKCS8EncodedKeySpec) + { + // get the DER-encoded Key according to PKCS#8 from the spec + byte[] encKey = ((PKCS8EncodedKeySpec)keySpec).getEncoded(); + + // decode the PKCS#8 data structure to the pki object + PrivateKeyInfo pki; + + try + { + pki = PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(encKey)); + } + catch (IOException e) + { + throw new InvalidKeySpecException("Unable to decode PKCS8EncodedKeySpec: " + e); + } + + try + { + // get the inner type inside the BIT STRING + ASN1Primitive innerType = pki.parsePrivateKey().toASN1Primitive(); + + // build and return the actual key + ASN1Sequence privKey = (ASN1Sequence)innerType; + + // decode oidString (but we don't need it right now) + String oidString = ((ASN1ObjectIdentifier)privKey.getObjectAt(0)) + .toString(); + + // decode <n> + BigInteger bigN = ((ASN1Integer)privKey.getObjectAt(1)).getValue(); + int n = bigN.intValue(); + + // decode <k> + BigInteger bigK = ((ASN1Integer)privKey.getObjectAt(2)).getValue(); + int k = bigK.intValue(); + + + // decode <fieldPoly> + byte[] encFieldPoly = ((ASN1OctetString)privKey.getObjectAt(3)) + .getOctets(); + // decode <goppaPoly> + byte[] encGoppaPoly = ((ASN1OctetString)privKey.getObjectAt(4)) + .getOctets(); + // decode <p> + byte[] encP = ((ASN1OctetString)privKey.getObjectAt(5)).getOctets(); + // decode <h> + byte[] encH = ((ASN1OctetString)privKey.getObjectAt(6)).getOctets(); + // decode <qInv> + ASN1Sequence qSeq = (ASN1Sequence)privKey.getObjectAt(7); + byte[][] encQInv = new byte[qSeq.size()][]; + for (int i = 0; i < qSeq.size(); i++) + { + encQInv[i] = ((ASN1OctetString)qSeq.getObjectAt(i)).getOctets(); + } + + return new BCMcElieceCCA2PrivateKey( + new McElieceCCA2PrivateKeySpec(OID, n, k, encFieldPoly, + encGoppaPoly, encP, encH, encQInv)); + + } + catch (IOException cce) + { + throw new InvalidKeySpecException( + "Unable to decode PKCS8EncodedKeySpec."); + } + } + + throw new InvalidKeySpecException("Unsupported key specification: " + + keySpec.getClass() + "."); + } + + /** + * Converts, if possible, a given key into a key specification. Currently, + * the following key specifications are supported: + * <ul> + * <li>for McElieceCCA2PublicKey: {@link X509EncodedKeySpec}, + * {@link McElieceCCA2PublicKeySpec}</li> + * <li>for McElieceCCA2PrivateKey: {@link PKCS8EncodedKeySpec}, + * {@link McElieceCCA2PrivateKeySpec}</li>. + * </ul> + * + * @param key the key + * @param keySpec the key specification + * @return the specification of the McEliece CCA2 key + * @throws InvalidKeySpecException if the key type or the key specification is not + * supported. + * @see BCMcElieceCCA2PrivateKey + * @see McElieceCCA2PrivateKeySpec + * @see BCMcElieceCCA2PublicKey + * @see McElieceCCA2PublicKeySpec + */ + public KeySpec getKeySpec(Key key, Class keySpec) + throws InvalidKeySpecException + { + if (key instanceof BCMcElieceCCA2PrivateKey) + { + if (PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)) + { + return new PKCS8EncodedKeySpec(key.getEncoded()); + } + else if (McElieceCCA2PrivateKeySpec.class + .isAssignableFrom(keySpec)) + { + BCMcElieceCCA2PrivateKey privKey = (BCMcElieceCCA2PrivateKey)key; + return new McElieceCCA2PrivateKeySpec(OID, privKey.getN(), privKey + .getK(), privKey.getField(), privKey.getGoppaPoly(), + privKey.getP(), privKey.getH(), privKey.getQInv()); + } + } + else if (key instanceof BCMcElieceCCA2PublicKey) + { + if (X509EncodedKeySpec.class.isAssignableFrom(keySpec)) + { + return new X509EncodedKeySpec(key.getEncoded()); + } + else if (McElieceCCA2PublicKeySpec.class + .isAssignableFrom(keySpec)) + { + BCMcElieceCCA2PublicKey pubKey = (BCMcElieceCCA2PublicKey)key; + return new McElieceCCA2PublicKeySpec(OID, pubKey.getN(), pubKey + .getT(), pubKey.getG()); + } + } + else + { + throw new InvalidKeySpecException("Unsupported key type: " + + key.getClass() + "."); + } + + throw new InvalidKeySpecException("Unknown key specification: " + + keySpec + "."); + } + + /** + * Translates a key into a form known by the FlexiProvider. Currently, only + * the following "source" keys are supported: {@link BCMcElieceCCA2PrivateKey}, + * {@link BCMcElieceCCA2PublicKey}. + * + * @param key the key + * @return a key of a known key type + * @throws InvalidKeyException if the key type is not supported. + */ + public Key translateKey(Key key) + throws InvalidKeyException + { + if ((key instanceof BCMcElieceCCA2PrivateKey) + || (key instanceof BCMcElieceCCA2PublicKey)) + { + return key; + } + throw new InvalidKeyException("Unsupported key type."); + + } + + + public PublicKey generatePublic(SubjectPublicKeyInfo pki) + throws InvalidKeySpecException + { + // get the inner type inside the BIT STRING + try + { + ASN1Primitive innerType = pki.parsePublicKey(); + McElieceCCA2PublicKey key = McElieceCCA2PublicKey.getInstance((ASN1Sequence)innerType); + return new BCMcElieceCCA2PublicKey(key.getOID().getId(), key.getN(), key.getT(), key.getG()); + } + catch (IOException cce) + { + throw new InvalidKeySpecException("Unable to decode X509EncodedKeySpec"); + } + } + + + public PrivateKey generatePrivate(PrivateKeyInfo pki) + throws InvalidKeySpecException + { + // get the inner type inside the BIT STRING + try + { + ASN1Primitive innerType = pki.parsePrivateKey().toASN1Primitive(); + McElieceCCA2PrivateKey key = McElieceCCA2PrivateKey.getInstance(innerType); + return new BCMcElieceCCA2PrivateKey(key.getOID().getId(), key.getN(), key.getK(), key.getField(), key.getGoppaPoly(), key.getP(), key.getH(), key.getQInv()); + } + catch (IOException cce) + { + throw new InvalidKeySpecException("Unable to decode PKCS8EncodedKeySpec"); + } + } + + protected PublicKey engineGeneratePublic(KeySpec keySpec) + throws InvalidKeySpecException + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + protected PrivateKey engineGeneratePrivate(KeySpec keySpec) + throws InvalidKeySpecException + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + protected KeySpec engineGetKeySpec(Key key, Class tClass) + throws InvalidKeySpecException + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + protected Key engineTranslateKey(Key key) + throws InvalidKeyException + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } +} |