use of com.github.zhenwei.core.asn1.BEROctetString in project pdfbox by apache.
the class AddValidationInformation method addOcspData.
/**
* Fetches and adds OCSP data to storage for the given Certificate.
*
* @param certInfo the certificate info, for it to check OCSP data.
* @throws IOException
* @throws OCSPException
* @throws CertificateProccessingException
* @throws RevokedCertificateException
*/
private void addOcspData(CertSignatureInformation certInfo) throws IOException, OCSPException, CertificateProccessingException, RevokedCertificateException {
if (ocspChecked.contains(certInfo.getCertificate())) {
// This certificate has been OCSP-checked before
return;
}
OcspHelper ocspHelper = new OcspHelper(certInfo.getCertificate(), signDate.getTime(), certInfo.getIssuerCertificate(), new HashSet<>(certInformationHelper.getCertificateSet()), certInfo.getOcspUrl());
OCSPResp ocspResp = ocspHelper.getResponseOcsp();
ocspChecked.add(certInfo.getCertificate());
BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResp.getResponseObject();
X509Certificate ocspResponderCertificate = ocspHelper.getOcspResponderCertificate();
certInformationHelper.addAllCertsFromHolders(basicResponse.getCerts());
byte[] signatureHash;
try {
// https://www.etsi.org/deliver/etsi_ts/102700_102799/10277804/01.01.02_60/ts_10277804v010102p.pdf
// "For the signatures of the CRL and OCSP response, it is the respective signature
// object represented as a BER-encoded OCTET STRING encoded with primitive encoding"
BEROctetString encodedSignature = new BEROctetString(basicResponse.getSignature());
signatureHash = MessageDigest.getInstance("SHA-1").digest(encodedSignature.getEncoded());
} catch (NoSuchAlgorithmException ex) {
throw new CertificateProccessingException(ex);
}
String signatureHashHex = Hex.getString(signatureHash);
if (!vriBase.containsKey(signatureHashHex)) {
COSArray savedCorrespondingOCSPs = correspondingOCSPs;
COSArray savedCorrespondingCRLs = correspondingCRLs;
COSDictionary vri = new COSDictionary();
vriBase.setItem(signatureHashHex, vri);
CertSignatureInformation ocspCertInfo = certInformationHelper.getCertInfo(ocspResponderCertificate);
updateVRI(ocspCertInfo, vri);
correspondingOCSPs = savedCorrespondingOCSPs;
correspondingCRLs = savedCorrespondingCRLs;
}
byte[] ocspData = ocspResp.getEncoded();
COSStream ocspStream = writeDataToStream(ocspData);
ocsps.add(ocspStream);
if (correspondingOCSPs != null) {
correspondingOCSPs.add(ocspStream);
}
foundRevocationInformation.add(certInfo.getCertificate());
}
use of com.github.zhenwei.core.asn1.BEROctetString in project pdfbox by apache.
the class TestCreateSignature method checkLTV.
private void checkLTV(File outFile) throws IOException, GeneralSecurityException, OCSPException, OperatorCreationException, CMSException {
try (PDDocument doc = Loader.loadPDF(outFile)) {
PDSignature signature = doc.getLastSignatureDictionary();
byte[] contents = signature.getContents();
PDDocumentCatalog docCatalog = doc.getDocumentCatalog();
COSDictionary dssDict = docCatalog.getCOSObject().getCOSDictionary(COSName.getPDFName("DSS"));
COSArray dssCertArray = dssDict.getCOSArray(COSName.getPDFName("Certs"));
COSDictionary vriDict = dssDict.getCOSDictionary(COSName.getPDFName("VRI"));
// Check that all known signature certificates are in the VRI/signaturehash/Cert array
byte[] signatureHash = MessageDigest.getInstance("SHA-1").digest(contents);
String hexSignatureHash = Hex.getString(signatureHash);
System.out.println("hexSignatureHash: " + hexSignatureHash);
CMSSignedData signedData = new CMSSignedData(contents);
Store<X509CertificateHolder> certificatesStore = signedData.getCertificates();
HashSet<X509CertificateHolder> certificateHolderSet = new HashSet<>(certificatesStore.getMatches(null));
COSDictionary sigDict = vriDict.getCOSDictionary(COSName.getPDFName(hexSignatureHash));
COSArray sigCertArray = sigDict.getCOSArray(COSName.getPDFName("Cert"));
Set<X509CertificateHolder> sigCertHolderSetFromVRIArray = new HashSet<>();
for (int i = 0; i < sigCertArray.size(); ++i) {
COSStream certStream = (COSStream) sigCertArray.getObject(i);
try (InputStream is = certStream.createInputStream()) {
sigCertHolderSetFromVRIArray.add(new X509CertificateHolder(IOUtils.toByteArray(is)));
}
}
for (X509CertificateHolder holder : certificateHolderSet) {
if (holder.getSubject().toString().contains("QuoVadis OCSP Authority Signature")) {
// not relevant here
continue;
}
// disabled until PDFBOX-5203 is fixed
// assertTrue(sigCertHolderSetFromVRIArray.contains(holder),
// "File '" + outFile + "' Root/DSS/VRI/" + hexSignatureHash +
// "/Cert array doesn't contain a certificate with subject '" +
// holder.getSubject() + "' and serial " + holder.getSerialNumber());
}
// Get all certificates. Each one should either be issued (= signed) by a certificate of the set
Set<X509Certificate> certSet = new HashSet<>();
for (int i = 0; i < dssCertArray.size(); ++i) {
COSStream certStream = (COSStream) dssCertArray.getObject(i);
try (InputStream is = certStream.createInputStream()) {
X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(is);
certSet.add(cert);
}
}
for (X509Certificate cert : certSet) {
boolean verified = false;
for (X509Certificate cert2 : certSet) {
try {
cert.verify(cert2.getPublicKey(), SecurityProvider.getProvider());
verified = true;
} catch (GeneralSecurityException ex) {
// not the issuer
}
}
// disabled until PDFBOX-5203 is fixed
// assertTrue(verified,
// "Certificate " + cert.getSubjectX500Principal() + " not issued by any certificate in the Certs array");
}
// Each CRL should be signed by one of the certificates in Certs
Set<X509CRL> crlSet = new HashSet<>();
COSArray crlArray = dssDict.getCOSArray(COSName.getPDFName("CRLs"));
for (int i = 0; i < crlArray.size(); ++i) {
COSStream crlStream = (COSStream) crlArray.getObject(i);
try (InputStream is = crlStream.createInputStream()) {
X509CRL cert = (X509CRL) certificateFactory.generateCRL(is);
crlSet.add(cert);
}
}
for (X509CRL crl : crlSet) {
boolean crlVerified = false;
X509Certificate crlIssuerCert = null;
for (X509Certificate cert : certSet) {
try {
crl.verify(cert.getPublicKey(), SecurityProvider.getProvider());
crlVerified = true;
crlIssuerCert = cert;
} catch (GeneralSecurityException ex) {
// not the issuer
}
}
assertTrue(crlVerified, "issuer of CRL not found in Certs array");
BEROctetString encodedSignature = new BEROctetString(crl.getSignature());
byte[] crlSignatureHash = MessageDigest.getInstance("SHA-1").digest(encodedSignature.getEncoded());
String hexCrlSignatureHash = Hex.getString(crlSignatureHash);
System.out.println("hexCrlSignatureHash: " + hexCrlSignatureHash);
// Check that the issueing certificate is in the VRI array
COSDictionary crlSigDict = vriDict.getCOSDictionary(COSName.getPDFName(hexCrlSignatureHash));
COSArray certArray2 = crlSigDict.getCOSArray(COSName.getPDFName("Cert"));
COSStream certStream = (COSStream) certArray2.getObject(0);
X509CertificateHolder certHolder2;
try (InputStream is2 = certStream.createInputStream()) {
certHolder2 = new X509CertificateHolder(IOUtils.toByteArray(is2));
}
assertEquals(certHolder2, new X509CertificateHolder(crlIssuerCert.getEncoded()), "CRL issuer certificate missing in VRI " + hexCrlSignatureHash);
}
Set<OCSPResp> oscpSet = new HashSet<>();
COSArray ocspArray = dssDict.getCOSArray(COSName.getPDFName("OCSPs"));
for (int i = 0; i < ocspArray.size(); ++i) {
COSStream ocspStream = (COSStream) ocspArray.getObject(i);
try (InputStream is = ocspStream.createInputStream()) {
OCSPResp ocspResp = new OCSPResp(is);
oscpSet.add(ocspResp);
}
}
for (OCSPResp ocspResp : oscpSet) {
BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResp.getResponseObject();
assertEquals(OCSPResponseStatus.SUCCESSFUL, ocspResp.getStatus());
assertTrue(basicResponse.getCerts().length >= 1, "OCSP should have at least 1 certificate");
BEROctetString encodedSignature = new BEROctetString(basicResponse.getSignature());
byte[] ocspSignatureHash = MessageDigest.getInstance("SHA-1").digest(encodedSignature.getEncoded());
String hexOcspSignatureHash = Hex.getString(ocspSignatureHash);
System.out.println("ocspSignatureHash: " + hexOcspSignatureHash);
long secondsOld = (System.currentTimeMillis() - basicResponse.getProducedAt().getTime()) / 1000;
assertTrue(secondsOld < 20, "OCSP answer is too old, is from " + secondsOld + " seconds ago");
X509CertificateHolder ocspCertHolder = basicResponse.getCerts()[0];
ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().setProvider(SecurityProvider.getProvider()).build(ocspCertHolder);
assertTrue(basicResponse.isSignatureValid(verifier));
COSDictionary ocspSigDict = vriDict.getCOSDictionary(COSName.getPDFName(hexOcspSignatureHash));
// Check that the Cert is in the VRI array
COSArray certArray2 = ocspSigDict.getCOSArray(COSName.getPDFName("Cert"));
COSStream certStream = (COSStream) certArray2.getObject(0);
X509CertificateHolder certHolder2;
try (InputStream is2 = certStream.createInputStream()) {
certHolder2 = new X509CertificateHolder(IOUtils.toByteArray(is2));
}
assertEquals(certHolder2, ocspCertHolder, "OCSP certificate is not in the VRI array");
}
}
}
use of com.github.zhenwei.core.asn1.BEROctetString in project LinLong-Java by zhenwei1108.
the class CMSAuthEnvelopedDataGenerator method doGenerate.
private CMSAuthEnvelopedData doGenerate(CMSTypedData content, OutputAEADEncryptor contentEncryptor) throws CMSException {
ASN1EncodableVector recipientInfos = new ASN1EncodableVector();
AlgorithmIdentifier encAlgId;
ASN1OctetString encContent;
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
ASN1Set authenticatedAttrSet = null;
try {
OutputStream cOut = contentEncryptor.getOutputStream(bOut);
content.write(cOut);
if (authAttrsGenerator != null) {
AttributeTable attrTable = authAttrsGenerator.getAttributes(Collections.EMPTY_MAP);
authenticatedAttrSet = new DERSet(attrTable.toASN1EncodableVector());
contentEncryptor.getAADStream().write(authenticatedAttrSet.getEncoded(ASN1Encoding.DER));
}
cOut.close();
} catch (IOException e) {
throw new CMSException("unable to process authenticated content: " + e.getMessage(), e);
}
byte[] encryptedContent = bOut.toByteArray();
byte[] mac = contentEncryptor.getMAC();
encAlgId = contentEncryptor.getAlgorithmIdentifier();
encContent = new BEROctetString(encryptedContent);
GenericKey encKey = contentEncryptor.getKey();
for (Iterator it = recipientInfoGenerators.iterator(); it.hasNext(); ) {
RecipientInfoGenerator recipient = (RecipientInfoGenerator) it.next();
recipientInfos.add(recipient.generate(encKey));
}
EncryptedContentInfo eci = new EncryptedContentInfo(content.getContentType(), encAlgId, encContent);
ASN1Set unprotectedAttrSet = null;
if (unauthAttrsGenerator != null) {
AttributeTable attrTable = unauthAttrsGenerator.getAttributes(Collections.EMPTY_MAP);
unprotectedAttrSet = new DLSet(attrTable.toASN1EncodableVector());
}
ContentInfo contentInfo = new ContentInfo(CMSObjectIdentifiers.authEnvelopedData, new AuthEnvelopedData(originatorInfo, new DERSet(recipientInfos), eci, authenticatedAttrSet, new DEROctetString(mac), unprotectedAttrSet));
return new CMSAuthEnvelopedData(contentInfo);
}
use of com.github.zhenwei.core.asn1.BEROctetString in project LinLong-Java by zhenwei1108.
the class CMSEncryptedDataGenerator method doGenerate.
private CMSEncryptedData doGenerate(CMSTypedData content, OutputEncryptor contentEncryptor) throws CMSException {
AlgorithmIdentifier encAlgId;
ASN1OctetString encContent;
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
try {
OutputStream cOut = contentEncryptor.getOutputStream(bOut);
content.write(cOut);
cOut.close();
} catch (IOException e) {
throw new CMSException("");
}
byte[] encryptedContent = bOut.toByteArray();
encAlgId = contentEncryptor.getAlgorithmIdentifier();
encContent = new BEROctetString(encryptedContent);
EncryptedContentInfo eci = new EncryptedContentInfo(content.getContentType(), encAlgId, encContent);
ASN1Set unprotectedAttrSet = null;
if (unprotectedAttributeGenerator != null) {
AttributeTable attrTable = unprotectedAttributeGenerator.getAttributes(Collections.EMPTY_MAP);
unprotectedAttrSet = new BERSet(attrTable.toASN1EncodableVector());
}
ContentInfo contentInfo = new ContentInfo(CMSObjectIdentifiers.encryptedData, new EncryptedData(eci, unprotectedAttrSet));
return new CMSEncryptedData(contentInfo);
}
use of com.github.zhenwei.core.asn1.BEROctetString in project LinLong-Java by zhenwei1108.
the class CMSEnvelopedDataGenerator method doGenerate.
private CMSEnvelopedData doGenerate(CMSTypedData content, OutputEncryptor contentEncryptor) throws CMSException {
ASN1EncodableVector recipientInfos = new ASN1EncodableVector();
AlgorithmIdentifier encAlgId;
ASN1OctetString encContent;
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
try {
OutputStream cOut = contentEncryptor.getOutputStream(bOut);
content.write(cOut);
cOut.close();
if (contentEncryptor instanceof OutputAEADEncryptor) {
byte[] mac = ((OutputAEADEncryptor) contentEncryptor).getMAC();
bOut.write(mac, 0, mac.length);
}
} catch (IOException e) {
throw new CMSException("");
}
byte[] encryptedContent = bOut.toByteArray();
encAlgId = contentEncryptor.getAlgorithmIdentifier();
encContent = new BEROctetString(encryptedContent);
GenericKey encKey = contentEncryptor.getKey();
for (Iterator it = recipientInfoGenerators.iterator(); it.hasNext(); ) {
RecipientInfoGenerator recipient = (RecipientInfoGenerator) it.next();
recipientInfos.add(recipient.generate(encKey));
}
EncryptedContentInfo eci = new EncryptedContentInfo(content.getContentType(), encAlgId, encContent);
ASN1Set unprotectedAttrSet = null;
if (unprotectedAttributeGenerator != null) {
AttributeTable attrTable = unprotectedAttributeGenerator.getAttributes(Collections.EMPTY_MAP);
unprotectedAttrSet = new BERSet(attrTable.toASN1EncodableVector());
}
ContentInfo contentInfo = new ContentInfo(CMSObjectIdentifiers.envelopedData, new EnvelopedData(originatorInfo, new DERSet(recipientInfos), eci, unprotectedAttrSet));
return new CMSEnvelopedData(contentInfo);
}
Aggregations