public ExtendedKeyUsage(final byte[] encoded) throws IOException {
   super(encoded);
   DERReader der = new DERReader(encoded);
   DERValue usageList = der.read();
   if (!usageList.isConstructed()) throw new IOException("malformed ExtKeyUsageSyntax");
   int len = 0;
   purposeIds = new LinkedList<OID>();
   while (len < usageList.getLength()) {
     DERValue val = der.read();
     if (val.getTag() != DER.OBJECT_IDENTIFIER) throw new IOException("malformed KeyPurposeId");
     purposeIds.add((OID) val.getValue());
     len += val.getEncodedLength();
   }
 }
  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)");
    }
  }
Example #3
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));
    }
  }