throw new IllegalArgumentException("can't decode PKCS7SignedData object");
}
if (!(pkcs instanceof ASN1Sequence)) {
throw new IllegalArgumentException("Not a valid PKCS#7 object - not a sequence");
}
ASN1Sequence signedData = (ASN1Sequence)pkcs;
DERObjectIdentifier objId = (DERObjectIdentifier)signedData.getObjectAt(0);
if (!objId.getId().equals(ID_PKCS7_SIGNED_DATA))
throw new IllegalArgumentException("Not a valid PKCS#7 object - not signed data");
ASN1Sequence content = (ASN1Sequence)((DERTaggedObject)signedData.getObjectAt(1)).getObject();
// the positions that we care are:
// 0 - version
// 1 - digestAlgorithms
// 2 - possible ID_PKCS7_DATA
// (the certificates and crls are taken out by other means)
// last - signerInfos
// the version
version = ((DERInteger)content.getObjectAt(0)).getValue().intValue();
// the digestAlgorithms
digestalgos = new HashSet();
Enumeration e = ((ASN1Set)content.getObjectAt(1)).getObjects();
while (e.hasMoreElements())
{
ASN1Sequence s = (ASN1Sequence)e.nextElement();
DERObjectIdentifier o = (DERObjectIdentifier)s.getObjectAt(0);
digestalgos.add(o.getId());
}
// the certificates and crls
X509CertParser cr = new X509CertParser();
cr.engineInit(new ByteArrayInputStream(contentsKey));
certs = cr.engineReadAll();
X509CRLParser cl = new X509CRLParser();
cl.engineInit(new ByteArrayInputStream(contentsKey));
crls = cl.engineReadAll();
// the possible ID_PKCS7_DATA
ASN1Sequence rsaData = (ASN1Sequence)content.getObjectAt(2);
if (rsaData.size() > 1) {
DEROctetString rsaDataContent = (DEROctetString)((DERTaggedObject)rsaData.getObjectAt(1)).getObject();
RSAdata = rsaDataContent.getOctets();
}
// the signerInfos
int next = 3;
while (content.getObjectAt(next) instanceof DERTaggedObject)
++next;
ASN1Set signerInfos = (ASN1Set)content.getObjectAt(next);
if (signerInfos.size() != 1)
throw new IllegalArgumentException("This PKCS#7 object has multiple SignerInfos - only one is supported at this time");
ASN1Sequence signerInfo = (ASN1Sequence)signerInfos.getObjectAt(0);
// the positions that we care are
// 0 - version
// 1 - the signing certificate serial number
// 2 - the digest algorithm
// 3 or 4 - digestEncryptionAlgorithm
// 4 or 5 - encryptedDigest
signerversion = ((DERInteger)signerInfo.getObjectAt(0)).getValue().intValue();
// Get the signing certificate
ASN1Sequence issuerAndSerialNumber = (ASN1Sequence)signerInfo.getObjectAt(1);
BigInteger serialNumber = ((DERInteger)issuerAndSerialNumber.getObjectAt(1)).getValue();
for (Iterator i = certs.iterator(); i.hasNext();) {
X509Certificate cert = (X509Certificate)i.next();
if (serialNumber.equals(cert.getSerialNumber())) {
signCert = cert;
break;
}
}
if (signCert == null) {
throw new IllegalArgumentException("Can't find signing certificate with serial " + serialNumber.toString(16));
}
digestAlgorithm = ((DERObjectIdentifier)((ASN1Sequence)signerInfo.getObjectAt(2)).getObjectAt(0)).getId();
next = 3;
if (signerInfo.getObjectAt(next) instanceof ASN1TaggedObject) {
ASN1TaggedObject tagsig = (ASN1TaggedObject)signerInfo.getObjectAt(next);
ASN1Sequence sseq = (ASN1Sequence)tagsig.getObject();
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
ASN1OutputStream dout = new ASN1OutputStream(bOut);
try {
ASN1EncodableVector attribute = new ASN1EncodableVector();
for (int k = 0; k < sseq.size(); ++k) {
attribute.add(sseq.getObjectAt(k));
}
dout.writeObject(new DERSet(attribute));
dout.close();
}
catch (IOException ioe){}
sigAttr = bOut.toByteArray();
for (int k = 0; k < sseq.size(); ++k) {
ASN1Sequence seq2 = (ASN1Sequence)sseq.getObjectAt(k);
if (((DERObjectIdentifier)seq2.getObjectAt(0)).getId().equals(ID_MESSAGE_DIGEST)) {
ASN1Set set = (ASN1Set)seq2.getObjectAt(1);
digestAttr = ((DEROctetString)set.getObjectAt(0)).getOctets();
break;
}
}
if (digestAttr == null)