use of sun.security.pkcs.SignerInfo in project portal by ixinportal.
the class SignTool method signP7.
/**
* 签名
*
* @param data
* 数据
* @return signature 签名结果
* @throws GeneralSecurityException
* @throws IOException
* @throws IllegalArgumentException
*/
public String signP7(byte[] data) throws Exception {
if (mode != SIGNER)
throw new IllegalStateException("call a PKCS7Tool instance not for signature.");
Signature signer = Signature.getInstance(signingAlgorithm);
signer.initSign(privateKey);
signer.update(data, 0, data.length);
byte[] signedAttributes = signer.sign();
ContentInfo contentInfo = null;
Field data_oidField = ContentInfo.class.getField("DATA_OID");
Object data_oid = data_oidField.get(null);
Constructor contentInfoConstructor = ContentInfo.class.getConstructor(new Class[] { data_oid.getClass(), derValue });
contentInfo = (ContentInfo) contentInfoConstructor.newInstance(new Object[] { data_oid, null });
// 根证书
X509Certificate x509 = certificates[0];
java.math.BigInteger serial = x509.getSerialNumber();
// X500Name
Constructor x500NameConstructor = x500Name.getConstructor(new Class[] { String.class });
Object x500NameObject = x500NameConstructor.newInstance(new Object[] { x509.getIssuerDN().getName() });
// AlgorithmId
Method algorithmIdGet = algorithmId.getMethod("get", new Class[] { String.class });
Object digestAlgorithmId = algorithmIdGet.invoke(null, new Object[] { digestAlgorithm });
Field algorithmIdfield = algorithmId.getField("RSAEncryption_oid");
Object rsaOid = algorithmIdfield.get(null);
Constructor algorithmConstructor = algorithmId.getConstructor(new Class[] { objectIdentifier });
Object algorithmRsaOid = algorithmConstructor.newInstance(new Object[] { rsaOid });
// SignerInfo
Constructor signerInfoConstructor = SignerInfo.class.getConstructor(new Class[] { x500Name, BigInteger.class, algorithmId, PKCS9Attributes.class, algorithmId, byte[].class, PKCS9Attributes.class });
// 签名信息
SignerInfo si = (SignerInfo) signerInfoConstructor.newInstance(new Object[] { // X500Name,
x500NameObject, // x509.getSerialNumber(), BigInteger serial,
serial, // AlgorithmId, digestAlgorithmId,
digestAlgorithmId, // PKCS9Attributes, authenticatedAttributes,
null, // AlgorithmId,
algorithmRsaOid, // byte[] encryptedDigest,
signedAttributes, // PKCS9Attributes unauthenticatedAttributes)
null });
SignerInfo[] signerInfos = { si };
// 构造PKCS7数据
Object digestAlgorithmIds = Array.newInstance(algorithmId, 1);
Array.set(digestAlgorithmIds, 0, digestAlgorithmId);
// PKCS7
Constructor pkcs7Constructor = PKCS7.class.getConstructor(new Class[] { digestAlgorithmIds.getClass(), ContentInfo.class, X509Certificate[].class, signerInfos.getClass() });
PKCS7 p7 = (PKCS7) pkcs7Constructor.newInstance(new Object[] { digestAlgorithmIds, contentInfo, certificates, signerInfos });
// PKCS7 p7 = new PKCS7(digestAlgorithmIds, contentInfo, certificates,
// signerInfos);
// public PKCS7(com.ibm.security.x509.AlgorithmId[] arg0,
// sun.security.pkcs.ContentInfo arg1,
// java.security.cert.X509Certificate[] arg2,
// sun.security.pkcs.SignerInfo[] arg3);
// public PKCS7(sun.security.x509.AlgorithmId[] arg0,
// sun.security.pkcs.ContentInfo arg1,
// java.security.cert.X509Certificate[] arg2,
// sun.security.pkcs.SignerInfo[] arg3);
ByteArrayOutputStream baout = new ByteArrayOutputStream();
p7.encodeSignedData(baout);
// Base64编码
return new BASE64Encoder().encode(baout.toByteArray());
}
use of sun.security.pkcs.SignerInfo in project Bytecoder by mirkosertic.
the class SignatureFileVerifier method getSigners.
/**
* Given the PKCS7 block and SignerInfo[], create an array of
* CodeSigner objects. We do this only *once* for a given
* signature block file.
*/
private CodeSigner[] getSigners(SignerInfo[] infos, PKCS7 block) throws IOException, NoSuchAlgorithmException, SignatureException, CertificateException {
ArrayList<CodeSigner> signers = null;
for (int i = 0; i < infos.length; i++) {
SignerInfo info = infos[i];
ArrayList<X509Certificate> chain = info.getCertificateChain(block);
CertPath certChain = certificateFactory.generateCertPath(chain);
if (signers == null) {
signers = new ArrayList<>();
}
// Append the new code signer
signers.add(new CodeSigner(certChain, info.getTimestamp()));
if (debug != null) {
debug.println("Signature Block Certificate: " + chain.get(0));
}
}
if (signers != null) {
return signers.toArray(new CodeSigner[signers.size()]);
} else {
return null;
}
}
use of sun.security.pkcs.SignerInfo in project Bytecoder by mirkosertic.
the class SignatureFileVerifier method processImpl.
private void processImpl(Hashtable<String, CodeSigner[]> signers, List<Object> manifestDigests) throws IOException, SignatureException, NoSuchAlgorithmException, JarException, CertificateException {
Manifest sf = new Manifest();
sf.read(new ByteArrayInputStream(sfBytes));
String version = sf.getMainAttributes().getValue(Attributes.Name.SIGNATURE_VERSION);
if ((version == null) || !(version.equalsIgnoreCase("1.0"))) {
// for now we just ignore this signature file
return;
}
SignerInfo[] infos = block.verify(sfBytes);
if (infos == null) {
throw new SecurityException("cannot verify signature block file " + name);
}
CodeSigner[] newSigners = getSigners(infos, block);
// make sure we have something to do all this work for...
if (newSigners == null)
return;
/*
* Look for the latest timestamp in the signature block. If an entry
* has no timestamp, use current time (aka null).
*/
for (CodeSigner s : newSigners) {
if (debug != null) {
debug.println("Gathering timestamp for: " + s.toString());
}
if (s.getTimestamp() == null) {
timestamp = null;
break;
} else if (timestamp == null) {
timestamp = s.getTimestamp();
} else {
if (timestamp.getTimestamp().before(s.getTimestamp().getTimestamp())) {
timestamp = s.getTimestamp();
}
}
}
Iterator<Map.Entry<String, Attributes>> entries = sf.getEntries().entrySet().iterator();
// see if we can verify the whole manifest first
boolean manifestSigned = verifyManifestHash(sf, md, manifestDigests);
// verify manifest main attributes
if (!manifestSigned && !verifyManifestMainAttrs(sf, md)) {
throw new SecurityException("Invalid signature file digest for Manifest main attributes");
}
// go through each section in the signature file
while (entries.hasNext()) {
Map.Entry<String, Attributes> e = entries.next();
String name = e.getKey();
if (manifestSigned || (verifySection(e.getValue(), name, md))) {
if (name.startsWith("./"))
name = name.substring(2);
if (name.startsWith("/"))
name = name.substring(1);
updateSigners(newSigners, signers, name);
if (debug != null) {
debug.println("processSignature signed name = " + name);
}
} else if (debug != null) {
debug.println("processSignature unsigned name = " + name);
}
}
// MANIFEST.MF is always regarded as signed
updateSigners(newSigners, signers, JarFile.MANIFEST_NAME);
}
use of sun.security.pkcs.SignerInfo in project bazel by bazelbuild.
the class SignedJarBuilder method writeSignatureBlock.
/** Write the certificate file with a digital signature. */
private void writeSignatureBlock(Signature signature, X509Certificate publicKey, PrivateKey privateKey) throws IOException, GeneralSecurityException {
SignerInfo signerInfo = new SignerInfo(new X500Name(publicKey.getIssuerX500Principal().getName()), publicKey.getSerialNumber(), AlgorithmId.get(DIGEST_ALGORITHM), AlgorithmId.get(privateKey.getAlgorithm()), signature.sign());
PKCS7 pkcs7 = new PKCS7(new AlgorithmId[] { AlgorithmId.get(DIGEST_ALGORITHM) }, new ContentInfo(ContentInfo.DATA_OID, null), new X509Certificate[] { publicKey }, new SignerInfo[] { signerInfo });
pkcs7.encodeSignedData(mOutputJar);
}
use of sun.security.pkcs.SignerInfo in project platform_frameworks_base by android.
the class RecoverySystem method verifyPackage.
/**
* Verify the cryptographic signature of a system update package
* before installing it. Note that the package is also verified
* separately by the installer once the device is rebooted into
* the recovery system. This function will return only if the
* package was successfully verified; otherwise it will throw an
* exception.
*
* Verification of a package can take significant time, so this
* function should not be called from a UI thread. Interrupting
* the thread while this function is in progress will result in a
* SecurityException being thrown (and the thread's interrupt flag
* will be cleared).
*
* @param packageFile the package to be verified
* @param listener an object to receive periodic progress
* updates as verification proceeds. May be null.
* @param deviceCertsZipFile the zip file of certificates whose
* public keys we will accept. Verification succeeds if the
* package is signed by the private key corresponding to any
* public key in this file. May be null to use the system default
* file (currently "/system/etc/security/otacerts.zip").
*
* @throws IOException if there were any errors reading the
* package or certs files.
* @throws GeneralSecurityException if verification failed
*/
public static void verifyPackage(File packageFile, ProgressListener listener, File deviceCertsZipFile) throws IOException, GeneralSecurityException {
final long fileLen = packageFile.length();
final RandomAccessFile raf = new RandomAccessFile(packageFile, "r");
try {
final long startTimeMillis = System.currentTimeMillis();
if (listener != null) {
listener.onProgress(0);
}
raf.seek(fileLen - 6);
byte[] footer = new byte[6];
raf.readFully(footer);
if (footer[2] != (byte) 0xff || footer[3] != (byte) 0xff) {
throw new SignatureException("no signature in file (no footer)");
}
final int commentSize = (footer[4] & 0xff) | ((footer[5] & 0xff) << 8);
final int signatureStart = (footer[0] & 0xff) | ((footer[1] & 0xff) << 8);
byte[] eocd = new byte[commentSize + 22];
raf.seek(fileLen - (commentSize + 22));
raf.readFully(eocd);
// end-of-central-directory record.
if (eocd[0] != (byte) 0x50 || eocd[1] != (byte) 0x4b || eocd[2] != (byte) 0x05 || eocd[3] != (byte) 0x06) {
throw new SignatureException("no signature in file (bad footer)");
}
for (int i = 4; i < eocd.length - 3; ++i) {
if (eocd[i] == (byte) 0x50 && eocd[i + 1] == (byte) 0x4b && eocd[i + 2] == (byte) 0x05 && eocd[i + 3] == (byte) 0x06) {
throw new SignatureException("EOCD marker found after start of EOCD");
}
}
// Parse the signature
PKCS7 block = new PKCS7(new ByteArrayInputStream(eocd, commentSize + 22 - signatureStart, signatureStart));
// Take the first certificate from the signature (packages
// should contain only one).
X509Certificate[] certificates = block.getCertificates();
if (certificates == null || certificates.length == 0) {
throw new SignatureException("signature contains no certificates");
}
X509Certificate cert = certificates[0];
PublicKey signatureKey = cert.getPublicKey();
SignerInfo[] signerInfos = block.getSignerInfos();
if (signerInfos == null || signerInfos.length == 0) {
throw new SignatureException("signature contains no signedData");
}
SignerInfo signerInfo = signerInfos[0];
// Check that the public key of the certificate contained
// in the package equals one of our trusted public keys.
boolean verified = false;
HashSet<X509Certificate> trusted = getTrustedCerts(deviceCertsZipFile == null ? DEFAULT_KEYSTORE : deviceCertsZipFile);
for (X509Certificate c : trusted) {
if (c.getPublicKey().equals(signatureKey)) {
verified = true;
break;
}
}
if (!verified) {
throw new SignatureException("signature doesn't match any trusted key");
}
// The signature cert matches a trusted key. Now verify that
// the digest in the cert matches the actual file data.
raf.seek(0);
final ProgressListener listenerForInner = listener;
SignerInfo verifyResult = block.verify(signerInfo, new InputStream() {
// The signature covers all of the OTA package except the
// archive comment and its 2-byte length.
long toRead = fileLen - commentSize - 2;
long soFar = 0;
int lastPercent = 0;
long lastPublishTime = startTimeMillis;
@Override
public int read() throws IOException {
throw new UnsupportedOperationException();
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
if (soFar >= toRead) {
return -1;
}
if (Thread.currentThread().isInterrupted()) {
return -1;
}
int size = len;
if (soFar + size > toRead) {
size = (int) (toRead - soFar);
}
int read = raf.read(b, off, size);
soFar += read;
if (listenerForInner != null) {
long now = System.currentTimeMillis();
int p = (int) (soFar * 100 / toRead);
if (p > lastPercent && now - lastPublishTime > PUBLISH_PROGRESS_INTERVAL_MS) {
lastPercent = p;
lastPublishTime = now;
listenerForInner.onProgress(lastPercent);
}
}
return read;
}
});
final boolean interrupted = Thread.interrupted();
if (listener != null) {
listener.onProgress(100);
}
if (interrupted) {
throw new SignatureException("verification was interrupted");
}
if (verifyResult == null) {
throw new SignatureException("signature digest verification failed");
}
} finally {
raf.close();
}
}
Aggregations