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;
  }
Beispiel #5
0
  /**
   * 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));
    }
  }