/** Get the "issuer" from the TBSCertificate bytes that are passed in */
 private DERObject getIssuer(byte[] enc) {
   try {
     ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream(enc));
     ASN1Sequence seq = (ASN1Sequence) in.readObject();
     return (DERObject) seq.getObjectAt(seq.getObjectAt(0) instanceof DERTaggedObject ? 3 : 2);
   } catch (IOException e) {
     throw new Error("IOException reading from ByteArray: " + e);
   }
 }
  /** Constructor from ASN1Sequence */
  public IssuingDistributionPoint(ASN1Sequence seq) {
    this.seq = seq;

    for (int i = 0; i != seq.size(); i++) {
      ASN1TaggedObject o = ASN1TaggedObject.getInstance(seq.getObjectAt(i));

      switch (o.getTagNo()) {
        case 0:
          // CHOICE so explicit
          distributionPoint = DistributionPointName.getInstance(o, true);
          break;
        case 1:
          onlyContainsUserCerts = DERBoolean.getInstance(o, false).isTrue();
          break;
        case 2:
          onlyContainsCACerts = DERBoolean.getInstance(o, false).isTrue();
          break;
        case 3:
          onlySomeReasons = new ReasonFlags(ReasonFlags.getInstance(o, false));
          break;
        case 4:
          indirectCRL = DERBoolean.getInstance(o, false).isTrue();
          break;
        case 5:
          onlyContainsAttributeCerts = DERBoolean.getInstance(o, false).isTrue();
          break;
        default:
          throw new IllegalArgumentException("unknown tag in IssuingDistributionPoint");
      }
    }
  }
  /** Read an existing PKCS#7 object from a DER encoded byte array */
  public PKCS7SignedData(byte[] in, String provider)
      throws SecurityException, CRLException, InvalidKeyException, NoSuchProviderException,
          NoSuchAlgorithmException {
    ASN1InputStream din = new ASN1InputStream(new ByteArrayInputStream(in));

    //
    // Basic checks to make sure it's a PKCS#7 SignedData Object
    //
    DERObject pkcs;

    try {
      pkcs = din.readObject();
    } catch (IOException e) {
      throw new SecurityException("can't decode PKCS7SignedData object");
    }

    if (!(pkcs instanceof ASN1Sequence)) {
      throw new SecurityException("Not a valid PKCS#7 object - not a sequence");
    }

    ContentInfo content = ContentInfo.getInstance(pkcs);

    if (!content.getContentType().equals(signedData)) {
      throw new SecurityException(
          "Not a valid PKCS#7 signed-data object - wrong header "
              + content.getContentType().getId());
    }

    SignedData data = SignedData.getInstance(content.getContent());

    certs = new ArrayList();

    if (data.getCertificates() != null) {
      Enumeration ec = ASN1Set.getInstance(data.getCertificates()).getObjects();

      while (ec.hasMoreElements()) {
        try {
          certs.add(
              new X509CertificateObject(X509CertificateStructure.getInstance(ec.nextElement())));
        } catch (CertificateParsingException e) {
          throw new SecurityException(e.toString());
        }
      }
    }

    crls = new ArrayList();

    if (data.getCRLs() != null) {
      Enumeration ec = ASN1Set.getInstance(data.getCRLs()).getObjects();
      while (ec.hasMoreElements()) {
        crls.add(new X509CRLObject(CertificateList.getInstance(ec.nextElement())));
      }
    }

    version = data.getVersion().getValue().intValue();

    //
    // Get the digest algorithm
    //
    digestalgos = new HashSet();
    Enumeration e = data.getDigestAlgorithms().getObjects();

    while (e.hasMoreElements()) {
      ASN1Sequence s = (ASN1Sequence) e.nextElement();
      DERObjectIdentifier o = (DERObjectIdentifier) s.getObjectAt(0);
      digestalgos.add(o.getId());
    }

    //
    // Get the SignerInfo
    //
    ASN1Set signerinfos = data.getSignerInfos();
    if (signerinfos.size() != 1) {
      throw new SecurityException(
          "This PKCS#7 object has multiple SignerInfos - only one is supported at this time");
    }

    SignerInfo signerInfo = SignerInfo.getInstance(signerinfos.getObjectAt(0));

    signerversion = signerInfo.getVersion().getValue().intValue();

    IssuerAndSerialNumber isAnds = signerInfo.getIssuerAndSerialNumber();

    //
    // Get the signing certificate
    //
    BigInteger serialNumber = isAnds.getCertificateSerialNumber().getValue();
    X509Principal issuer = new X509Principal(isAnds.getName());

    for (Iterator i = certs.iterator(); i.hasNext(); ) {
      X509Certificate cert = (X509Certificate) i.next();
      if (serialNumber.equals(cert.getSerialNumber()) && issuer.equals(cert.getIssuerDN())) {
        signCert = cert;
        break;
      }
    }

    if (signCert == null) {
      throw new SecurityException(
          "Can't find signing certificate with serial " + serialNumber.toString(16));
    }

    digestAlgorithm = signerInfo.getDigestAlgorithm().getObjectId().getId();

    digest = signerInfo.getEncryptedDigest().getOctets();
    digestEncryptionAlgorithm = signerInfo.getDigestEncryptionAlgorithm().getObjectId().getId();

    sig = Signature.getInstance(getDigestAlgorithm(), provider);

    sig.initVerify(signCert.getPublicKey());
  }