/** * 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() + "."); }
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"); } }
private PemObject createPemObject(Object o) throws IOException { String type; byte[] encoding; if (o instanceof PemObject) { return (PemObject) o; } if (o instanceof PemObjectGenerator) { return ((PemObjectGenerator) o).generate(); } if (o instanceof X509Certificate) { type = "CERTIFICATE"; try { encoding = ((X509Certificate) o).getEncoded(); } catch (CertificateEncodingException e) { throw new PemGenerationException("Cannot encode object: " + e.toString()); } } else if (o instanceof X509CRL) { type = "X509 CRL"; try { encoding = ((X509CRL) o).getEncoded(); } catch (CRLException e) { throw new PemGenerationException("Cannot encode object: " + e.toString()); } } else if (o instanceof KeyPair) { return createPemObject(((KeyPair) o).getPrivate()); } else if (o instanceof PrivateKey) { PrivateKeyInfo info = new PrivateKeyInfo((ASN1Sequence) ASN1Primitive.fromByteArray(((Key) o).getEncoded())); if (o instanceof RSAPrivateKey) { type = "RSA PRIVATE KEY"; encoding = info.parsePrivateKey().toASN1Primitive().getEncoded(); } else if (o instanceof DSAPrivateKey) { type = "DSA PRIVATE KEY"; DSAParameter p = DSAParameter.getInstance(info.getPrivateKeyAlgorithm().getParameters()); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERInteger(0)); v.add(new DERInteger(p.getP())); v.add(new DERInteger(p.getQ())); v.add(new DERInteger(p.getG())); BigInteger x = ((DSAPrivateKey) o).getX(); BigInteger y = p.getG().modPow(x, p.getP()); v.add(new DERInteger(y)); v.add(new DERInteger(x)); encoding = new DERSequence(v).getEncoded(); } else if (((PrivateKey) o).getAlgorithm().equals("ECDSA")) { type = "EC PRIVATE KEY"; encoding = info.parsePrivateKey().toASN1Primitive().getEncoded(); } else { throw new IOException("Cannot identify private key"); } } else if (o instanceof PublicKey) { type = "PUBLIC KEY"; encoding = ((PublicKey) o).getEncoded(); } else if (o instanceof X509AttributeCertificate) { type = "ATTRIBUTE CERTIFICATE"; encoding = ((X509V2AttributeCertificate) o).getEncoded(); } else if (o instanceof PKCS10CertificationRequest) { type = "CERTIFICATE REQUEST"; encoding = ((PKCS10CertificationRequest) o).getEncoded(); } else if (o instanceof ContentInfo) { type = "PKCS7"; encoding = ((ContentInfo) o).getEncoded(); } else { throw new PemGenerationException("unknown object passed - can't encode."); } return new PemObject(type, encoding); }
private PemObject createPemObject( Object obj, String algorithm, char[] password, SecureRandom random) throws IOException { if (obj instanceof KeyPair) { return createPemObject(((KeyPair) obj).getPrivate(), algorithm, password, random); } String type = null; byte[] keyData = null; if (obj instanceof RSAPrivateCrtKey) { type = "RSA PRIVATE KEY"; RSAPrivateCrtKey k = (RSAPrivateCrtKey) obj; org.bouncycastle.asn1.pkcs.RSAPrivateKey keyStruct = new org.bouncycastle.asn1.pkcs.RSAPrivateKey( k.getModulus(), k.getPublicExponent(), k.getPrivateExponent(), k.getPrimeP(), k.getPrimeQ(), k.getPrimeExponentP(), k.getPrimeExponentQ(), k.getCrtCoefficient()); // convert to bytearray keyData = keyStruct.getEncoded(); } else if (obj instanceof DSAPrivateKey) { type = "DSA PRIVATE KEY"; DSAPrivateKey k = (DSAPrivateKey) obj; DSAParams p = k.getParams(); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERInteger(0)); v.add(new DERInteger(p.getP())); v.add(new DERInteger(p.getQ())); v.add(new DERInteger(p.getG())); BigInteger x = k.getX(); BigInteger y = p.getG().modPow(x, p.getP()); v.add(new DERInteger(y)); v.add(new DERInteger(x)); keyData = new DERSequence(v).getEncoded(); } else if (obj instanceof PrivateKey && "ECDSA".equals(((PrivateKey) obj).getAlgorithm())) { type = "EC PRIVATE KEY"; PrivateKeyInfo privInfo = PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(((PrivateKey) obj).getEncoded())); keyData = privInfo.parsePrivateKey().toASN1Primitive().getEncoded(); } if (type == null || keyData == null) { // TODO Support other types? throw new IllegalArgumentException("Object type not supported: " + obj.getClass().getName()); } String dekAlgName = Strings.toUpperCase(algorithm); // Note: For backward compatibility if (dekAlgName.equals("DESEDE")) { dekAlgName = "DES-EDE3-CBC"; } int ivLength = dekAlgName.startsWith("AES-") ? 16 : 8; byte[] iv = new byte[ivLength]; random.nextBytes(iv); byte[] encData = PEMUtilities.crypt(true, provider, keyData, password, dekAlgName, iv); List headers = new ArrayList(2); headers.add(new PemHeader("Proc-Type", "4,ENCRYPTED")); headers.add(new PemHeader("DEK-Info", dekAlgName + "," + getHexEncoded(iv))); return new PemObject(type, headers, encData); }