public static boolean isValidSignature(CMSSignedData signedData, X509Certificate rootCert) throws Exception { boolean[] bArr = new boolean[2]; bArr[0] = true; CertStore certsAndCRLs = signedData.getCertificatesAndCRLs("Collection", "BC"); SignerInformationStore signers = signedData.getSignerInfos(); Iterator it = signers.getSigners().iterator(); if (it.hasNext()) { SignerInformation signer = (SignerInformation) it.next(); SignerId signerConstraints = signer.getSID(); signerConstraints.setKeyUsage(bArr); PKIXCertPathBuilderResult result = buildPath(rootCert, signer.getSID(), certsAndCRLs); return signer.verify(result.getPublicKey(), "BC"); } return false; }
@Test public void testCMSSignature() throws Exception { // setup byte[] toBeSigned = "hello world".getBytes(); String signatureDescription = "Test CMS Signature"; CMSTestSignatureService signatureService = new CMSTestSignatureService(toBeSigned, signatureDescription); KeyPair keyPair = PkiTestUtils.generateKeyPair(); DateTime notBefore = new DateTime(); DateTime notAfter = notBefore.plusYears(1); X509Certificate certificate = PkiTestUtils.generateCertificate( keyPair.getPublic(), "CN=Test", notBefore, notAfter, null, keyPair.getPrivate(), true, 0, null, null, new KeyUsage(KeyUsage.nonRepudiation)); List<X509Certificate> signingCertificateChain = new LinkedList<X509Certificate>(); signingCertificateChain.add(certificate); // operate DigestInfo digestInfo = signatureService.preSign(null, signingCertificateChain, null, null, null); // verify assertNotNull(digestInfo); byte[] digestValue = digestInfo.digestValue; LOG.debug("digest value: " + Hex.encodeHexString(digestValue)); assertNotNull(digestValue); assertEquals(signatureDescription, digestInfo.description); assertEquals("SHA1", digestInfo.digestAlgo); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPrivate()); byte[] digestInfoValue = ArrayUtils.addAll(PkiTestUtils.SHA1_DIGEST_INFO_PREFIX, digestValue); byte[] signatureValue = cipher.doFinal(digestInfoValue); LOG.debug("signature value: " + Hex.encodeHexString(signatureValue)); // operate signatureService.postSign(signatureValue, signingCertificateChain); // verify byte[] cmsSignature = signatureService.getCMSSignature(); CMSSignedData signedData = new CMSSignedData(cmsSignature); SignerInformationStore signers = signedData.getSignerInfos(); Iterator<SignerInformation> iter = signers.getSigners().iterator(); while (iter.hasNext()) { SignerInformation signer = iter.next(); SignerId signerId = signer.getSID(); assertTrue(signerId.match(certificate)); assertTrue(signer.verify(keyPair.getPublic(), BouncyCastleProvider.PROVIDER_NAME)); } byte[] data = (byte[]) signedData.getSignedContent().getContent(); assertArrayEquals(toBeSigned, data); }
public boolean doJob() { String strMethod = "doJob()"; try { // _validateCmsSignature(); CMSSignedData cms = _getSignPkcs7(); SignerInformationStore sis = cms.getSignerInfos(); Collection colSignerInfo = sis.getSigners(); Iterator itrSignerInfo = colSignerInfo.iterator(); SignerInformation sin = (SignerInformation) itrSignerInfo.next(); // r�cup�ration du certificat du signataire CertStore cse = cms.getCertificatesAndCRLs("Collection", CmsVerif._STR_KST_PROVIDER_BC); Iterator itrCert = cse.getCertificates(sin.getSID()).iterator(); X509Certificate crt = (X509Certificate) itrCert.next(); // Verifie la signature boolean blnCoreValidity = sin.verify(crt, CmsVerif._STR_KST_PROVIDER_BC); if (blnCoreValidity) { MySystem.s_printOutTrace(this, strMethod, "blnCoreValidity=true"); String strBody = "CMS Detached signature is OK!"; strBody += "\n\n" + ". CMS signature file location:"; strBody += "\n " + super._strPathAbsFileSig_; strBody += "\n\n" + ". Data file location:"; strBody += "\n " + super._strPathAbsFileData_; OPAbstract.s_showDialogInfo(super._frmOwner_, strBody); // SignerInfo sio = sin.toSignerInfo(); SignerId sid = sin.getSID(); if (sid != null) { System.out.println("sid.getSerialNumber()=" + sid.getSerialNumber()); System.out.println("sid.getIssuerAsString()=" + sid.getIssuerAsString()); System.out.println("sid.getSubjectAsString()=" + sid.getSubjectAsString()); } /*System.out.println("sin.getDigestAlgOID()=" + sin.getDigestAlgOID()); System.out.println("sin.getEncryptionAlgOID()=" + sin.getEncryptionAlgOID()); System.out.println("sin.toString()=" + sin.toString()); System.out.println("sin.getVersion()=" + sin.getVersion());*/ } else { MySystem.s_printOutWarning(this, strMethod, "blnCoreValidity=true"); String strBody = "CMS Detached signature is WRONG!"; strBody += "\n\n" + ". CMS signature file location:"; strBody += "\n " + super._strPathAbsFileSig_; strBody += "\n\n" + ". Data file location:"; strBody += "\n " + super._strPathAbsFileData_; OPAbstract.s_showDialogWarning(super._frmOwner_, strBody); } } catch (Exception exc) { exc.printStackTrace(); MySystem.s_printOutError(this, strMethod, "exc caught"); String strBody = "Failed to verify CMS detached signature."; strBody += "\n\n" + "Possible reason: wrong data file"; strBody += "\n\n" + "got exception."; strBody += "\n" + exc.getMessage(); strBody += "\n\n" + "More: see your session.log"; OPAbstract.s_showDialogError(super._frmOwner_, strBody); return false; } // TODO return true; }
public byte[] timeStamp(byte[] data, RevocationData revocationData) throws Exception { // digest the message MessageDigest messageDigest = MessageDigest.getInstance(this.digestAlgo); byte[] digest = messageDigest.digest(data); // generate the TSP request BigInteger nonce = new BigInteger(128, new SecureRandom()); TimeStampRequestGenerator requestGenerator = new TimeStampRequestGenerator(); requestGenerator.setCertReq(true); if (null != this.requestPolicy) { requestGenerator.setReqPolicy(this.requestPolicy); } TimeStampRequest request = requestGenerator.generate(this.digestAlgoOid, digest, nonce); byte[] encodedRequest = request.getEncoded(); // create the HTTP client HttpClient httpClient = new HttpClient(); if (null != this.username) { Credentials credentials = new UsernamePasswordCredentials(this.username, this.password); httpClient.getState().setCredentials(AuthScope.ANY, credentials); } if (null != this.proxyHost) { httpClient.getHostConfiguration().setProxy(this.proxyHost, this.proxyPort); } // create the HTTP POST request PostMethod postMethod = new PostMethod(this.tspServiceUrl); RequestEntity requestEntity = new ByteArrayRequestEntity(encodedRequest, "application/timestamp-query"); postMethod.addRequestHeader("User-Agent", this.userAgent); postMethod.setRequestEntity(requestEntity); // invoke TSP service int statusCode = httpClient.executeMethod(postMethod); if (HttpStatus.SC_OK != statusCode) { LOG.error("Error contacting TSP server " + this.tspServiceUrl); throw new Exception("Error contacting TSP server " + this.tspServiceUrl); } // HTTP input validation Header responseContentTypeHeader = postMethod.getResponseHeader("Content-Type"); if (null == responseContentTypeHeader) { throw new RuntimeException("missing Content-Type header"); } String contentType = responseContentTypeHeader.getValue(); if (!contentType.startsWith("application/timestamp-reply")) { LOG.debug("response content: " + postMethod.getResponseBodyAsString()); throw new RuntimeException("invalid Content-Type: " + contentType); } if (0 == postMethod.getResponseContentLength()) { throw new RuntimeException("Content-Length is zero"); } // TSP response parsing and validation InputStream inputStream = postMethod.getResponseBodyAsStream(); TimeStampResponse timeStampResponse = new TimeStampResponse(inputStream); timeStampResponse.validate(request); if (0 != timeStampResponse.getStatus()) { LOG.debug("status: " + timeStampResponse.getStatus()); LOG.debug("status string: " + timeStampResponse.getStatusString()); PKIFailureInfo failInfo = timeStampResponse.getFailInfo(); if (null != failInfo) { LOG.debug("fail info int value: " + failInfo.intValue()); if (PKIFailureInfo.unacceptedPolicy == failInfo.intValue()) { LOG.debug("unaccepted policy"); } } throw new RuntimeException( "timestamp response status != 0: " + timeStampResponse.getStatus()); } TimeStampToken timeStampToken = timeStampResponse.getTimeStampToken(); SignerId signerId = timeStampToken.getSID(); BigInteger signerCertSerialNumber = signerId.getSerialNumber(); X500Principal signerCertIssuer = signerId.getIssuer(); LOG.debug("signer cert serial number: " + signerCertSerialNumber); LOG.debug("signer cert issuer: " + signerCertIssuer); // TSP signer certificates retrieval CertStore certStore = timeStampToken.getCertificatesAndCRLs("Collection", BouncyCastleProvider.PROVIDER_NAME); Collection<? extends Certificate> certificates = certStore.getCertificates(null); X509Certificate signerCert = null; Map<String, X509Certificate> certificateMap = new HashMap<String, X509Certificate>(); for (Certificate certificate : certificates) { X509Certificate x509Certificate = (X509Certificate) certificate; if (signerCertIssuer.equals(x509Certificate.getIssuerX500Principal()) && signerCertSerialNumber.equals(x509Certificate.getSerialNumber())) { signerCert = x509Certificate; } String ski = Hex.encodeHexString(getSubjectKeyId(x509Certificate)); certificateMap.put(ski, x509Certificate); LOG.debug( "embedded certificate: " + x509Certificate.getSubjectX500Principal() + "; SKI=" + ski); } // TSP signer cert path building if (null == signerCert) { throw new RuntimeException("TSP response token has no signer certificate"); } List<X509Certificate> tspCertificateChain = new LinkedList<X509Certificate>(); X509Certificate certificate = signerCert; do { LOG.debug("adding to certificate chain: " + certificate.getSubjectX500Principal()); tspCertificateChain.add(certificate); if (certificate.getSubjectX500Principal().equals(certificate.getIssuerX500Principal())) { break; } String aki = Hex.encodeHexString(getAuthorityKeyId(certificate)); certificate = certificateMap.get(aki); } while (null != certificate); // verify TSP signer signature timeStampToken.validate(tspCertificateChain.get(0), BouncyCastleProvider.PROVIDER_NAME); // verify TSP signer certificate this.validator.validate(tspCertificateChain, revocationData); LOG.debug("time-stamp token time: " + timeStampToken.getTimeStampInfo().getGenTime()); byte[] timestamp = timeStampToken.getEncoded(); return timestamp; }