private void decode() throws IOException { DERReader der = new DERReader(encoded); DERValue val = der.read(); if (val.getTag() != DER.SEQUENCE) throw new IOException("malformed EncryptedPrivateKeyInfo"); val = der.read(); if (val.getTag() != DER.SEQUENCE) throw new IOException("malformed AlgorithmIdentifier"); int algpLen = val.getLength(); DERValue oid = der.read(); if (oid.getTag() != DER.OBJECT_IDENTIFIER) throw new IOException("malformed AlgorithmIdentifier"); algOid = (OID) oid.getValue(); if (algpLen == 0) { val = der.read(); if (val.getTag() != 0) { encodedParams = val.getEncoded(); der.read(); } } else if (oid.getEncodedLength() < val.getLength()) { val = der.read(); encodedParams = val.getEncoded(); } val = der.read(); if (val.getTag() != DER.OCTET_STRING) throw new IOException("malformed AlgorithmIdentifier"); encryptedData = (byte[]) val.getValue(); }
public NameConstraints(byte[] encoded) throws IOException { super(encoded); DERReader der = new DERReader(encoded); DERValue value = der.read(); if (!value.isConstructed()) { throw new IOException("malformed NameConstraints"); } permittedSubtrees = new LinkedList<GeneralSubtree>(); excludedSubtrees = new LinkedList<GeneralSubtree>(); int len = 0; if (len < value.getLength()) { DERValue subtrees = der.read(); if (subtrees.getTag() == 0) { int len2 = 0; while (len2 < subtrees.getLength()) { DERValue subtree = der.read(); permittedSubtrees.add(new GeneralSubtree(subtree.getEncoded())); der.skip(subtree.getLength()); len2 += subtree.getEncodedLength(); } len += subtrees.getEncodedLength(); if (len < value.getLength()) { subtrees = der.read(); if (subtrees.getTag() != 1) throw new IOException( "unexpected tag " + subtrees.getTag() + " (expecting 1 for excludedSubtrees)"); len2 = 0; while (len2 < subtrees.getLength()) { DERValue subtree = der.read(); excludedSubtrees.add(new GeneralSubtree(subtree.getEncoded())); der.skip(subtree.getLength()); len2 += subtree.getEncodedLength(); } } } else if (subtrees.getTag() == 1) { int len2 = 0; while (len2 < subtrees.getLength()) { DERValue subtree = der.read(); excludedSubtrees.add(new GeneralSubtree(subtree.getEncoded())); der.skip(subtree.getLength()); len2 += subtree.getEncodedLength(); } } else throw new IOException("unexpected tag " + subtrees.getTag() + " (expecting 0 or 1)"); } }
public byte[] getEncoded() { if (encodedKey != null) return (byte[]) encodedKey.clone(); ArrayList key = new ArrayList(2); key.add(new DERValue(DER.INTEGER, getModulus())); key.add(new DERValue(DER.INTEGER, getPublicExponent())); DERValue rsapk = new DERValue(DER.SEQUENCE | DER.CONSTRUCTED, key); ArrayList alg = new ArrayList(2); alg.add(new DERValue(DER.OBJECT_IDENTIFIER, new OID("1.2.840.113549.1.1.1"))); alg.add(new DERValue(DER.NULL, null)); ArrayList spki = new ArrayList(2); spki.add(new DERValue(DER.SEQUENCE | DER.CONSTRUCTED, alg)); spki.add(new DERValue(DER.BIT_STRING, new BitString(rsapk.getEncoded()))); encodedKey = new DERValue(DER.SEQUENCE | DER.CONSTRUCTED, spki).getEncoded(); return (byte[]) encodedKey.clone(); }
/** * @param aliasName * @param publicKey * @param privateKey * @return the DER encoded Certificate Signing Request. * @throws IOException * @throws InvalidKeyException * @throws SignatureException */ private byte[] getCSR(X500Principal aliasName, PublicKey publicKey, PrivateKey privateKey) throws IOException, InvalidKeyException, SignatureException { DERValue derVersion = new DERValue(DER.INTEGER, BigInteger.ZERO); DERValue derSubject = new DERReader(aliasName.getEncoded()).read(); DERValue derSubjectPKInfo = new DERReader(publicKey.getEncoded()).read(); byte[] b = nullAttributes ? new byte[] {0x05, 0x00} : new byte[0]; DERValue derAttributes = new DERValue(DER.CONSTRUCTED | DER.CONTEXT | 0, b.length, b, null); ArrayList certRequestInfo = new ArrayList(4); certRequestInfo.add(derVersion); certRequestInfo.add(derSubject); certRequestInfo.add(derSubjectPKInfo); certRequestInfo.add(derAttributes); DERValue derCertRequestInfo = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, certRequestInfo); OID sigAlgorithmID = getSignatureAlgorithmOID(); DERValue derSigAlgorithmID = new DERValue(DER.OBJECT_IDENTIFIER, sigAlgorithmID); ArrayList sigAlgorithm = new ArrayList(2); sigAlgorithm.add(derSigAlgorithmID); if (!sigAlgorithmID.equals(Command.SHA1_WITH_DSA)) // it's an RSA-based sigAlgorithm.add(new DERValue(DER.NULL, null)); sigAlgorithm.trimToSize(); DERValue derSignatureAlgorithm = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, sigAlgorithm); signatureAlgorithm.initSign(privateKey); signatureAlgorithm.update(derCertRequestInfo.getEncoded()); byte[] sigBytes = signatureAlgorithm.sign(); DERValue derSignature = new DERValue(DER.BIT_STRING, new BitString(sigBytes)); ArrayList csr = new ArrayList(3); csr.add(derCertRequestInfo); csr.add(derSignatureAlgorithm); csr.add(derSignature); DERValue derCSR = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, csr); ByteArrayOutputStream baos = new ByteArrayOutputStream(); DERWriter.write(baos, derCSR); byte[] result = baos.toByteArray(); return result; }
/** * Parse an encoded PKCS#7 SignedData object. The ASN.1 format of this object is: * * <pre> * SignedData ::= SEQUENCE { * version Version, -- always 1 for PKCS7 v1.5 * digestAlgorithms DigestAlgorithmIdentifiers, * contentInfo ContentInfo, * certificates [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL, * crls [1] IMPLICIT CertificateRevocationLists OPTIONAL, * signerInfos SignerInfos } * * Version ::= INTEGER * * DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier * * DigestAlgorithmIdentifier ::= AlgorithmIdentifier * * ContentInfo ::= SEQUENCE { * contentType ContentType, * content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL } * * ContentType ::= OBJECT IDENTIFIER * * ExtendedCertificatesAndCertificates ::= * SET OF ExtendedCertificatesAndCertificate * * ExtendedCertificatesAndCertificate ::= CHOICE { * certificate Certificate, -- from X.509 * extendedCertificate [0] IMPLICIT ExtendedCertificate } * * CertificateRevocationLists ::= SET OF CertificateRevocationList * -- from X.509 * * SignerInfos ::= SET OF SignerInfo * * SignerInfo ::= SEQUENCE { * version Version, -- always 1 for PKCS7 v1.5 * issuerAndSerialNumber IssuerAndSerialNumber, * digestAlgorithm DigestAlgorithmIdentifier, * authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL, * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier, * encryptedDigest EncryptedDigest, * unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL } * * EncryptedDigest ::= OCTET STRING * </pre> * * <p>(Readers who are confused as to why it takes 40 levels of indirection to specify "data with * a signature", rest assured that the present author is as confused as you are). */ public PKCS7SignedData(BERReader ber) throws CRLException, CertificateException, IOException { CertificateFactory x509 = CertificateFactory.getInstance("X509"); DERValue val = ber.read(); if (!val.isConstructed()) throw new BEREncodingException("malformed ContentInfo"); val = ber.read(); if (val.getTag() != BER.OBJECT_IDENTIFIER) throw new BEREncodingException("malformed ContentType"); if (!PKCS7_SIGNED_DATA.equals(val.getValue())) throw new BEREncodingException("content is not SignedData"); val = ber.read(); if (val.getTag() != 0) throw new BEREncodingException("malformed Content"); val = ber.read(); if (!val.isConstructed()) throw new BEREncodingException("malformed SignedData"); if (Configuration.DEBUG) log.fine("SignedData: " + val); val = ber.read(); if (val.getTag() != BER.INTEGER) throw new BEREncodingException("expecting Version"); version = (BigInteger) val.getValue(); if (Configuration.DEBUG) log.fine(" Version: " + version); digestAlgorithms = new HashSet(); val = ber.read(); if (!val.isConstructed()) throw new BEREncodingException("malformed DigestAlgorithmIdentifiers"); if (Configuration.DEBUG) log.fine(" DigestAlgorithmIdentifiers: " + val); int count = 0; DERValue val2 = ber.read(); while (val2 != BER.END_OF_SEQUENCE && (val.getLength() > 0 && val.getLength() > count)) { if (!val2.isConstructed()) throw new BEREncodingException("malformed AlgorithmIdentifier"); if (Configuration.DEBUG) log.fine(" AlgorithmIdentifier: " + val2); count += val2.getEncodedLength(); val2 = ber.read(); if (val2.getTag() != BER.OBJECT_IDENTIFIER) throw new BEREncodingException("malformed AlgorithmIdentifier"); if (Configuration.DEBUG) log.fine(" digestAlgorithmIdentifiers OID: " + val2.getValue()); List algId = new ArrayList(2); algId.add(val2.getValue()); val2 = ber.read(); if (val2 != BER.END_OF_SEQUENCE) { count += val2.getEncodedLength(); if (val2.getTag() == BER.NULL) algId.add(null); else algId.add(val2.getEncoded()); if (val2.isConstructed()) ber.skip(val2.getLength()); if (BERValue.isIndefinite(val)) val2 = ber.read(); } else algId.add(null); if (Configuration.DEBUG) { log.fine(" digestAlgorithmIdentifiers params: "); log.fine( Util.dumpString((byte[]) algId.get(1), " digestAlgorithmIdentifiers params: ")); } digestAlgorithms.add(algId); } val = ber.read(); if (!val.isConstructed()) throw new BEREncodingException("malformed ContentInfo"); if (Configuration.DEBUG) log.fine(" ContentInfo: " + val); val2 = ber.read(); if (val2.getTag() != BER.OBJECT_IDENTIFIER) throw new BEREncodingException("malformed ContentType"); contentType = (OID) val2.getValue(); if (Configuration.DEBUG) log.fine(" ContentType OID: " + contentType); if (BERValue.isIndefinite(val) || (val.getLength() > 0 && val.getLength() > val2.getEncodedLength())) { val2 = ber.read(); if (val2 != BER.END_OF_SEQUENCE) { content = val2.getEncoded(); if (BERValue.isIndefinite(val)) val2 = ber.read(); } } if (Configuration.DEBUG) { log.fine(" Content: "); log.fine(Util.dumpString(content, " Content: ")); } val = ber.read(); if (val.getTag() == 0) { if (!val.isConstructed()) throw new BEREncodingException("malformed ExtendedCertificatesAndCertificates"); if (Configuration.DEBUG) log.fine(" ExtendedCertificatesAndCertificates: " + val); count = 0; val2 = ber.read(); List certs = new LinkedList(); while (val2 != BER.END_OF_SEQUENCE && (val.getLength() > 0 && val.getLength() > count)) { Certificate cert = x509.generateCertificate(new ByteArrayInputStream(val2.getEncoded())); if (Configuration.DEBUG) log.fine(" Certificate: " + cert); certs.add(cert); count += val2.getEncodedLength(); ber.skip(val2.getLength()); if (BERValue.isIndefinite(val) || val.getLength() > count) val2 = ber.read(); } certificates = (Certificate[]) certs.toArray(new Certificate[certs.size()]); val = ber.read(); } if (val.getTag() == 1) { if (!val.isConstructed()) throw new BEREncodingException("malformed CertificateRevocationLists"); if (Configuration.DEBUG) log.fine(" CertificateRevocationLists: " + val); count = 0; val2 = ber.read(); List crls = new LinkedList(); while (val2 != BER.END_OF_SEQUENCE && (val.getLength() > 0 && val.getLength() > count)) { CRL crl = x509.generateCRL(new ByteArrayInputStream(val2.getEncoded())); if (Configuration.DEBUG) log.fine(" CRL: " + crl); crls.add(crl); count += val2.getEncodedLength(); ber.skip(val2.getLength()); if (BERValue.isIndefinite(val) || val.getLength() > count) val2 = ber.read(); } this.crls = (CRL[]) crls.toArray(new CRL[crls.size()]); val = ber.read(); } signerInfos = new HashSet(); if (!val.isConstructed()) throw new BEREncodingException("malformed SignerInfos"); if (Configuration.DEBUG) log.fine(" SignerInfos: " + val); // FIXME read this more carefully. // Since we are just reading a file (probably) we just read until we // reach the end. while (true) { int i = ber.peek(); if (i == 0 || i == -1) break; signerInfos.add(new SignerInfo(ber)); } }