use of org.bouncycastle.cms.CMSSignedData in project pdfbox by apache.
the class ShowSignature method showSignature.
private void showSignature(String[] args) throws IOException, CertificateException, NoSuchAlgorithmException, NoSuchProviderException, TSPException {
if (args.length != 2) {
usage();
} else {
String password = args[0];
File infile = new File(args[1]);
try (PDDocument document = PDDocument.load(infile, password)) {
for (PDSignature sig : document.getSignatureDictionaries()) {
COSDictionary sigDict = sig.getCOSObject();
COSString contents = (COSString) sigDict.getDictionaryObject(COSName.CONTENTS);
// download the signed content
byte[] buf;
try (FileInputStream fis = new FileInputStream(infile)) {
buf = sig.getSignedContent(fis);
}
System.out.println("Signature found");
int[] byteRange = sig.getByteRange();
if (byteRange.length != 4) {
System.err.println("Signature byteRange must have 4 items");
} else {
long fileLen = infile.length();
long rangeMax = byteRange[2] + (long) byteRange[3];
// multiply content length with 2 (because it is in hex in the PDF) and add 2 for < and >
int contentLen = contents.getString().length() * 2 + 2;
if (fileLen != rangeMax || byteRange[0] != 0 || byteRange[1] + contentLen != byteRange[2]) {
// a false result doesn't necessarily mean that the PDF is a fake
// see this answer why:
// https://stackoverflow.com/a/48185913/535646
System.out.println("Signature does not cover whole document");
} else {
System.out.println("Signature covers whole document");
}
}
if (sig.getName() != null) {
System.out.println("Name: " + sig.getName());
}
if (sig.getSignDate() != null) {
System.out.println("Modified: " + sdf.format(sig.getSignDate().getTime()));
}
String subFilter = sig.getSubFilter();
if (subFilter != null) {
switch(subFilter) {
case "adbe.pkcs7.detached":
case "ETSI.CAdES.detached":
verifyPKCS7(buf, contents, sig);
// TODO check certificate chain, revocation lists, timestamp...
break;
case "adbe.pkcs7.sha1":
{
// example: PDFBOX-1452.pdf
byte[] certData = contents.getBytes();
CertificateFactory factory = CertificateFactory.getInstance("X.509");
ByteArrayInputStream certStream = new ByteArrayInputStream(certData);
Collection<? extends Certificate> certs = factory.generateCertificates(certStream);
System.out.println("certs=" + certs);
byte[] hash = MessageDigest.getInstance("SHA1").digest(buf);
verifyPKCS7(hash, contents, sig);
// TODO check certificate chain, revocation lists, timestamp...
break;
}
case "adbe.x509.rsa_sha1":
{
// example: PDFBOX-2693.pdf
COSString certString = (COSString) sigDict.getDictionaryObject(COSName.CERT);
if (certString == null) {
System.err.println("The /Cert certificate string is missing in the signature dictionary");
return;
}
byte[] certData = certString.getBytes();
CertificateFactory factory = CertificateFactory.getInstance("X.509");
ByteArrayInputStream certStream = new ByteArrayInputStream(certData);
Collection<? extends Certificate> certs = factory.generateCertificates(certStream);
System.out.println("certs=" + certs);
// TODO verify signature
break;
}
case "ETSI.RFC3161":
TimeStampToken timeStampToken = new TimeStampToken(new CMSSignedData(contents.getBytes()));
System.out.println("Time stamp gen time: " + timeStampToken.getTimeStampInfo().getGenTime());
System.out.println("Time stamp tsa name: " + timeStampToken.getTimeStampInfo().getTsa().getName());
CertificateFactory factory = CertificateFactory.getInstance("X.509");
ByteArrayInputStream certStream = new ByteArrayInputStream(contents.getBytes());
Collection<? extends Certificate> certs = factory.generateCertificates(certStream);
System.out.println("certs=" + certs);
// TODO verify signature
break;
default:
System.err.println("Unknown certificate type: " + subFilter);
break;
}
} else {
throw new IOException("Missing subfilter for cert dictionary");
}
}
analyseDSS(document);
} catch (CMSException | OperatorCreationException ex) {
throw new IOException(ex);
}
System.out.println("Analyzed: " + args[1]);
}
}
use of org.bouncycastle.cms.CMSSignedData in project pdfbox by apache.
the class TestCreateSignature method checkSignature.
// This check fails with a file created with the code before PDFBOX-3011 was solved.
private void checkSignature(File file) throws IOException, CMSException, OperatorCreationException, GeneralSecurityException {
try (PDDocument document = PDDocument.load(file)) {
List<PDSignature> signatureDictionaries = document.getSignatureDictionaries();
if (signatureDictionaries.isEmpty()) {
Assert.fail("no signature found");
}
for (PDSignature sig : document.getSignatureDictionaries()) {
COSString contents = (COSString) sig.getCOSObject().getDictionaryObject(COSName.CONTENTS);
byte[] buf;
try (FileInputStream fis = new FileInputStream(file)) {
buf = sig.getSignedContent(fis);
}
// inspiration:
// http://stackoverflow.com/a/26702631/535646
// http://stackoverflow.com/a/9261365/535646
CMSSignedData signedData = new CMSSignedData(new CMSProcessableByteArray(buf), contents.getBytes());
Store certificatesStore = signedData.getCertificates();
Collection<SignerInformation> signers = signedData.getSignerInfos().getSigners();
SignerInformation signerInformation = signers.iterator().next();
Collection matches = certificatesStore.getMatches(signerInformation.getSID());
X509CertificateHolder certificateHolder = (X509CertificateHolder) matches.iterator().next();
X509Certificate certFromSignedData = new JcaX509CertificateConverter().getCertificate(certificateHolder);
Assert.assertEquals(certificate, certFromSignedData);
// CMSVerifierCertificateNotValidException means that the keystore wasn't valid at signing time
if (!signerInformation.verify(new JcaSimpleSignerInfoVerifierBuilder().build(certFromSignedData))) {
Assert.fail("Signature verification failed");
}
break;
}
}
}
use of org.bouncycastle.cms.CMSSignedData 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);
}
JcaSignerInfoGeneratorBuilder siGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(digCalcProv);
// 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);
}
}
use of org.bouncycastle.cms.CMSSignedData in project xipki by xipki.
the class ScepResponder method createSignedData.
private ContentInfo createSignedData(Certificate cert) throws CaException {
CMSSignedDataGenerator cmsSignedDataGen = new CMSSignedDataGenerator();
CMSSignedData cmsSigneddata;
try {
cmsSignedDataGen.addCertificate(new X509CertificateHolder(cert));
if (control.isSendCaCert()) {
cmsSignedDataGen.addCertificate(new X509CertificateHolder(caEmulator.getCaCert()));
}
cmsSigneddata = cmsSignedDataGen.generate(new CMSAbsentContent());
} catch (CMSException ex) {
throw new CaException(ex);
}
return cmsSigneddata.toASN1Structure();
}
use of org.bouncycastle.cms.CMSSignedData in project xipki by xipki.
the class Client method scepGetCrl.
public X509CRL scepGetCrl(PrivateKey identityKey, X509Certificate identityCert, X500Name issuer, BigInteger serialNumber) throws ScepClientException {
ScepUtil.requireNonNull("identityKey", identityKey);
ScepUtil.requireNonNull("identityCert", identityCert);
ScepUtil.requireNonNull("issuer", issuer);
ScepUtil.requireNonNull("serialNumber", serialNumber);
initIfNotInited();
PkiMessage pkiMessage = new PkiMessage(TransactionId.randomTransactionId(), MessageType.GetCRL);
IssuerAndSerialNumber isn = new IssuerAndSerialNumber(issuer, serialNumber);
pkiMessage.setMessageData(isn);
ContentInfo request = encryptThenSign(pkiMessage, identityKey, identityCert);
ScepHttpResponse httpResp = httpSend(Operation.PKIOperation, request);
CMSSignedData cmsSignedData = parsePkiMessage(httpResp.getContentBytes());
PkiMessage response = decode(cmsSignedData, identityKey, identityCert);
if (response.getPkiStatus() != PkiStatus.SUCCESS) {
throw new ScepClientException("server returned " + response.getPkiStatus());
}
ContentInfo messageData = ContentInfo.getInstance(response.getMessageData());
try {
return ScepUtil.getCrlFromPkiMessage(SignedData.getInstance(messageData.getContent()));
} catch (CRLException ex) {
throw new ScepClientException(ex.getMessage(), ex);
}
}
Aggregations