JarUtilspublic class JarUtils extends Object
Fields Summary |
---|
private static final int[] | MESSAGE_DIGEST_OID |
Methods Summary |
---|
private static java.security.cert.X509Certificate[] | createChain(java.security.cert.X509Certificate signer, java.security.cert.X509Certificate[] candidates)
LinkedList chain = new LinkedList();
chain.add(0, signer);
// Signer is self-signed
if (signer.getSubjectDN().equals(signer.getIssuerDN())){
return (X509Certificate[])chain.toArray(new X509Certificate[1]);
}
Principal issuer = signer.getIssuerDN();
X509Certificate issuerCert;
int count = 1;
while (true) {
issuerCert = findCert(issuer, candidates);
if( issuerCert == null) {
break;
}
chain.add(issuerCert);
count++;
if (issuerCert.getSubjectDN().equals(issuerCert.getIssuerDN())) {
break;
}
issuer = issuerCert.getIssuerDN();
}
return (X509Certificate[])chain.toArray(new X509Certificate[count]);
| private static java.security.cert.X509Certificate | findCert(java.security.Principal issuer, java.security.cert.X509Certificate[] candidates)
for (int i = 0; i < candidates.length; i++) {
if (issuer.equals(candidates[i].getSubjectDN())) {
return candidates[i];
}
}
return null;
| public static java.security.cert.Certificate[] | verifySignature(java.io.InputStream signature, java.io.InputStream signatureBlock)This method handle all the work with PKCS7, ASN1 encoding, signature verifying,
and certification path building.
See also PKCS #7: Cryptographic Message Syntax Standard:
http://www.ietf.org/rfc/rfc2315.txt
BerInputStream bis = new BerInputStream(signatureBlock);
ContentInfo info = (ContentInfo)ContentInfo.ASN1.decode(bis);
SignedData signedData = info.getSignedData();
if (signedData == null) {
throw new IOException(Messages.getString("security.173")); //$NON-NLS-1$
}
Collection encCerts = signedData.getCertificates();
if (encCerts.isEmpty()) {
return null;
}
X509Certificate[] certs = new X509Certificate[encCerts.size()];
int i = 0;
for (Iterator it = encCerts.iterator(); it.hasNext();) {
certs[i++]= new X509CertImpl((org.apache.harmony.security.x509.Certificate)it.next());
}
List sigInfos = signedData.getSignerInfos();
SignerInfo sigInfo;
if (!sigInfos.isEmpty()) {
sigInfo = (SignerInfo)sigInfos.get(0);
} else {
return null;
}
// Issuer
X500Principal issuer = sigInfo.getIssuer();
// Certificate serial number
BigInteger snum = sigInfo.getSerialNumber();
// Locate the certificate
int issuerSertIndex = 0;
for (i = 0; i < certs.length; i++) {
if (issuer.equals(certs[i].getIssuerDN()) &&
snum.equals(certs[i].getSerialNumber())) {
issuerSertIndex = i;
break;
}
}
if (i == certs.length) { // No issuer certificate found
return null;
}
if (certs[issuerSertIndex].hasUnsupportedCriticalExtension()) {
throw new SecurityException(Messages.getString("security.174")); //$NON-NLS-1$
}
// Get Signature instance
Signature sig = null;
String da = sigInfo.getdigestAlgorithm();
String dea = sigInfo.getDigestEncryptionAlgorithm();
String alg = null;
if (da != null && dea != null) {
alg = da + "with" + dea; //$NON-NLS-1$
try{
// BEGIN android-removed
// sig = OpenSSLSignature.getInstance(alg);
// END android-removed
// BEGIN android-added
sig = OpenSSLSignature.getInstance(alg);
// END android-removed
} catch (NoSuchAlgorithmException e) {}
}
if (sig == null) {
alg = da;
if (alg == null) {
return null;
}
try{
// BEGIN android-removed
// sig = OpenSSLSignature.getInstance(alg);
// END android-removed
// BEGIN android-added
sig = OpenSSLSignature.getInstance(alg);
// END android-removed
} catch (NoSuchAlgorithmException e) {
return null;
}
}
sig.initVerify(certs[issuerSertIndex]);
// If the authenticatedAttributes field of SignerInfo contains more than zero attributes,
// compute the message digest on the ASN.1 DER encoding of the Attributes value.
// Otherwise, compute the message digest on the data.
List atr = sigInfo.getAuthenticatedAttributes();
byte[] sfBytes = new byte[signature.available()];
signature.read(sfBytes);
if (atr == null) {
sig.update(sfBytes);
} else {
sig.update(sigInfo.getEncodedAuthenticatedAttributes());
// If the authenticatedAttributes field contains the message-digest attribute,
// verify that it equals the computed digest of the signature file
byte[] existingDigest = null;
for (Iterator it = atr.iterator(); it.hasNext();) {
AttributeTypeAndValue a = (AttributeTypeAndValue)it.next();
if (Arrays.equals(a.getType().getOid(), MESSAGE_DIGEST_OID) ){
//TODO value existingDigest = a.AttributeValue;
}
}
if (existingDigest != null) {
// BEGIN android-removed
// MessageDigest md = MessageDigest.getInstance(sigInfo.getDigestAlgorithm());
// END android-removed
// BEGIN android-added
MessageDigest md = OpenSSLMessageDigestJDK.getInstance(sigInfo.getDigestAlgorithm());
// END android-added
byte[] computedDigest = md.digest(sfBytes);
if (!Arrays.equals(existingDigest, computedDigest)) {
throw new SecurityException(Messages.getString("security.175")); //$NON-NLS-1$
}
}
}
if (!sig.verify(sigInfo.getEncryptedDigest())) {
throw new SecurityException(Messages.getString("security.176")); //$NON-NLS-1$
}
return createChain(certs[issuerSertIndex], certs);
|
|