예제 #1
0
  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);
  }
예제 #3
0
  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;
  }