use of org.bouncycastle.asn1.x509.Time in project pdfbox by apache.
the class TestCreateSignature method testDetachedSHA256WithTSA.
/**
* Signs a PDF using the "adbe.pkcs7.detached" SubFilter with the SHA-256 digest and a signed
* timestamp from a Time Stamping Authority (TSA) server.
*
* This is not a complete test because we don't have the ability to return a valid response, so
* we return a cached response which is well-formed, but does not match the timestamp or nonce
* in the request. This allows us to test the basic TSA mechanism and test the nonce, which is a
* good start.
*
* @throws IOException
* @throws GeneralSecurityException
* @throws CMSException
* @throws OperatorCreationException
* @throws TSPException
* @throws CertificateVerificationException
*/
@ParameterizedTest
@MethodSource("signingTypes")
void testDetachedSHA256WithTSA(boolean externallySign) throws IOException, CMSException, OperatorCreationException, GeneralSecurityException, TSPException, CertificateVerificationException {
// mock TSA response content
byte[] content = Files.readAllBytes(Paths.get(IN_DIR, TSA_RESPONSE));
// mock TSA server (RFC 3161)
MockHttpServer mockServer = new MockHttpServer(externallySign ? 15371 : 15372);
mockServer.startServer();
String brokenMockTSA = "http://localhost:" + mockServer.getServerPort() + "/";
MockHttpServer.MockHttpServerResponse response = new MockHttpServer.MockHttpServerResponse();
response.setMockResponseContent(content);
response.setMockResponseContentType("application/timestamp-reply");
response.setMockResponseCode(200);
mockServer.setMockHttpServerResponses(response);
String inPath = IN_DIR + "sign_me_tsa.pdf";
String outPath = OUT_DIR + getOutputFileName("signed{0}_tsa.pdf", externallySign);
// sign PDF (will fail due to nonce and timestamp differing)
CreateSignature signing1 = new CreateSignature(keyStore, PASSWORD.toCharArray());
signing1.setExternalSigning(externallySign);
try {
signing1.signDetached(new File(inPath), new File(outPath), brokenMockTSA);
fail("This should have failed");
} catch (IOException e) {
assertTrue(e.getCause() instanceof TSPValidationException);
new File(outPath).delete();
}
mockServer.stopServer();
Assumptions.assumeTrue(tsa != null && !tsa.isEmpty(), "No TSA URL defined, test skipped");
CreateSignature signing2 = new CreateSignature(keyStore, PASSWORD.toCharArray());
signing2.setExternalSigning(externallySign);
signing2.signDetached(new File(inPath), new File(outPath), tsa);
checkSignature(new File(inPath), new File(outPath), true);
System.out.println("TSA test successful");
}
use of org.bouncycastle.asn1.x509.Time in project pdfbox by apache.
the class OcspHelper method verifyOcspResponse.
/**
* Verifies the status and the response itself (including nonce), but not the signature.
*
* @param ocspResponse to be verified
* @throws OCSPException
* @throws RevokedCertificateException
* @throws IOException if the default security provider can't be instantiated
*/
private void verifyOcspResponse(OCSPResp ocspResponse) throws OCSPException, RevokedCertificateException, IOException {
verifyRespStatus(ocspResponse);
BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject();
if (basicResponse != null) {
ResponderID responderID = basicResponse.getResponderId().toASN1Primitive();
// https://tools.ietf.org/html/rfc6960#section-4.2.2.3
// The basic response type contains:
// (...)
// either the name of the responder or a hash of the responder's
// public key as the ResponderID
// (...)
// The responder MAY include certificates in the certs field of
// BasicOCSPResponse that help the OCSP client verify the responder's
// signature.
X500Name name = responderID.getName();
if (name != null) {
findResponderCertificateByName(basicResponse, name);
} else {
byte[] keyHash = responderID.getKeyHash();
if (keyHash != null) {
findResponderCertificateByKeyHash(basicResponse, keyHash);
} else {
throw new OCSPException("OCSP: basic response must provide name or key hash");
}
}
if (ocspResponderCertificate == null) {
throw new OCSPException("OCSP: certificate for responder " + name + " not found");
}
try {
SigUtils.checkResponderCertificateUsage(ocspResponderCertificate);
} catch (CertificateParsingException ex) {
// unlikely to happen because the certificate existed as an object
LOG.error(ex, ex);
}
checkOcspSignature(ocspResponderCertificate, basicResponse);
boolean nonceChecked = checkNonce(basicResponse);
SingleResp[] responses = basicResponse.getResponses();
if (responses.length != 1) {
throw new OCSPException("OCSP: Received " + responses.length + " responses instead of 1!");
}
SingleResp resp = responses[0];
Object status = resp.getCertStatus();
if (!nonceChecked) {
// https://tools.ietf.org/html/rfc5019
// fall back to validating the OCSPResponse based on time
checkOcspResponseFresh(resp);
}
if (status instanceof RevokedStatus) {
RevokedStatus revokedStatus = (RevokedStatus) status;
if (revokedStatus.getRevocationTime().compareTo(signDate) <= 0) {
throw new RevokedCertificateException("OCSP: Certificate is revoked since " + revokedStatus.getRevocationTime(), revokedStatus.getRevocationTime());
}
LOG.info("The certificate was revoked after signing by OCSP " + ocspUrl + " on " + revokedStatus.getRevocationTime());
} else if (status != CertificateStatus.GOOD) {
throw new OCSPException("OCSP: Status of Cert is unknown");
}
}
}
use of org.bouncycastle.asn1.x509.Time in project keystore-explorer by kaikramer.
the class Asn1Dump method dumpUTCTime.
private String dumpUTCTime(ASN1UTCTime asn1Time) {
StringBuilder sb = new StringBuilder();
sb.append(indentSequence.toString(indentLevel));
sb.append("UTC TIME=");
// UTCTime, note does not support ms precision hence the different date format
Date date;
try {
date = asn1Time.getDate();
} catch (ParseException e) {
throw new RuntimeException("Cannot parse utc time");
}
String formattedDate = new SimpleDateFormat("dd/MMM/yyyy HH:mm:ss z").format(date);
sb.append(formattedDate);
sb.append(" (");
sb.append(asn1Time.getTime());
sb.append(")");
sb.append(NEWLINE);
return sb.toString();
}
use of org.bouncycastle.asn1.x509.Time in project keystore-explorer by kaikramer.
the class Asn1Dump method dumpGeneralizedTime.
private String dumpGeneralizedTime(ASN1GeneralizedTime asn1Time) {
StringBuilder sb = new StringBuilder();
sb.append(indentSequence.toString(indentLevel));
sb.append("GENERALIZED TIME=");
Date date;
try {
date = asn1Time.getDate();
} catch (ParseException e) {
throw new RuntimeException("Cannot parse generalized time");
}
String formattedDate = new SimpleDateFormat("dd/MMM/yyyy HH:mm:ss.SSS z").format(date);
sb.append(formattedDate);
sb.append(" (");
sb.append(asn1Time.getTime());
sb.append(")");
sb.append(NEWLINE);
return sb.toString();
}
use of org.bouncycastle.asn1.x509.Time in project keystore-explorer by kaikramer.
the class JarSigner method createSignatureBlock.
private static byte[] createSignatureBlock(byte[] toSign, PrivateKey privateKey, X509Certificate[] certificateChain, SignatureType signatureType, String tsaUrl, Provider provider) throws CryptoException {
try {
List<X509Certificate> certList = new ArrayList<>();
Collections.addAll(certList, certificateChain);
DigestCalculatorProvider digCalcProv = new JcaDigestCalculatorProviderBuilder().setProvider("BC").build();
JcaContentSignerBuilder csb = new JcaContentSignerBuilder(signatureType.jce()).setSecureRandom(SecureRandom.getInstance("SHA1PRNG"));
if (provider != null) {
csb.setProvider(provider);
}
// Workaround for display issue in verify function of jarsigner for Java <= 15
// see https://github.com/kaikramer/keystore-explorer/issues/293
JcaSignerInfoGeneratorBuilder siGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(digCalcProv, new DefaultCMSSignatureEncryptionAlgorithmFinder() {
@Override
public AlgorithmIdentifier findEncryptionAlgorithm(AlgorithmIdentifier signatureAlgorithm) {
List<ASN1ObjectIdentifier> shaRsaIdentifiers = Arrays.asList(PKCSObjectIdentifiers.sha256WithRSAEncryption, PKCSObjectIdentifiers.sha384WithRSAEncryption, PKCSObjectIdentifiers.sha512WithRSAEncryption);
// map OIDs for RSAwithSHA256/384/512 to OID for RSAEncryption
return shaRsaIdentifiers.contains(signatureAlgorithm.getAlgorithm()) ? new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE) : super.findEncryptionAlgorithm(signatureAlgorithm);
}
});
// remove cmsAlgorithmProtect for compatibility reasons
SignerInfoGenerator sigGen = siGeneratorBuilder.build(csb.build(privateKey), certificateChain[0]);
final CMSAttributeTableGenerator sAttrGen = sigGen.getSignedAttributeTableGenerator();
sigGen = new SignerInfoGenerator(sigGen, new DefaultSignedAttributeTableGenerator() {
@Override
public AttributeTable getAttributes(@SuppressWarnings("rawtypes") Map parameters) {
AttributeTable ret = sAttrGen.getAttributes(parameters);
return ret.remove(CMSAttributes.cmsAlgorithmProtect);
}
}, sigGen.getUnsignedAttributeTableGenerator());
CMSSignedDataGenerator dataGen = new CMSSignedDataGenerator();
dataGen.addSignerInfoGenerator(sigGen);
dataGen.addCertificates(new JcaCertStore(certList));
CMSSignedData signedData = dataGen.generate(new CMSProcessableByteArray(toSign), true);
// now let TSA time-stamp the signature
if (tsaUrl != null && !tsaUrl.isEmpty()) {
signedData = addTimestamp(tsaUrl, signedData);
}
return signedData.getEncoded();
} catch (Exception ex) {
throw new CryptoException(res.getString("SignatureBlockCreationFailed.exception.message"), ex);
}
}
Aggregations