List of usage examples for org.bouncycastle.asn1.cmp PKIMessage getProtection
public DERBitString getProtection()
From source file:org.ejbca.core.protocol.cmp.authentication.EndEntityCertificateAuthenticationModule.java
License:Open Source License
@Override /*/*from ww w .j av a 2 s . c om*/ * Verifies the signature of 'msg'. msg should be signed and the signer's certificate should be * attached in msg in the extraCert field. * * When successful, the authentication string is set. */ public boolean verifyOrExtract(final PKIMessage msg, final String username) { //Check that msg is signed if (msg.getProtection() == null) { this.errorMessage = "PKI Message is not athenticated properly. No PKI protection is found."; return false; } // Read the extraCert and store it in a local variable extraCert = getExtraCert(msg); if (extraCert == null) { this.errorMessage = "Error while reading the certificate in the extraCert field"; return false; } boolean vendormode = impl.isVendorCertificateMode(msg.getBody().getType(), this.confAlias); boolean omitVerifications = cmpConfiguration.getOmitVerificationsInEEC(confAlias); boolean ramode = cmpConfiguration.getRAMode(confAlias); if (log.isDebugEnabled()) { log.debug("CMP is operating in RA mode: " + this.cmpConfiguration.getRAMode(this.confAlias)); log.debug("CMP is operating in Vendor mode: " + vendormode); log.debug("CMP message already been authenticated: " + authenticated); log.debug("Omitting som verifications: " + omitVerifications); } //---------------------------------------------------------------------------------------- // Perform the different checks depending on the configuration and previous authentication //---------------------------------------------------------------------------------------- // Not allowed combinations. if (ramode && vendormode) { this.errorMessage = "Vendor mode and RA mode cannot be combined"; return false; } if (omitVerifications && (!ramode || !authenticated)) { this.errorMessage = "Omitting some verifications can only be accepted in RA mode and when the " + "CMP request has already been authenticated, for example, through the use of NestedMessageContent"; return false; } // Accepted combinations if (omitVerifications && ramode && authenticated) { // Do nothing here if (log.isDebugEnabled()) { log.debug( "Skipping some verification of the extraCert certificate in RA mode and an already authenticated CMP message, tex. through NestedMessageContent"); } } else if (ramode) { // Get the CA to use for the authentication CAInfo cainfo = getCAInfoByName(authenticationparameter); if (cainfo == null) return false; // Check that extraCert is in the Database CertificateInfo certinfo = certSession.getCertificateInfo(CertTools.getFingerprintAsString(extraCert)); if (certinfo == null) { this.errorMessage = "The certificate attached to the PKIMessage in the extraCert field could not be found in the database."; return false; } // More extraCert verifications if (!isExtraCertIssuedByCA(cainfo) || !isExtraCertValid() || !isExtraCertActive(certinfo)) { return false; } // Check that extraCert belong to an admin with sufficient access rights if (!isAuthorizedAdmin(certinfo, msg, cainfo.getCAId())) { this.errorMessage = "'" + CertTools.getSubjectDN(extraCert) + "' is not an authorized administrator."; return false; } } else if (!ramode) { // client mode String extraCertUsername = null; if (vendormode) { // Check that extraCert is issued by a configured VendorCA if (!impl.isExtraCertIssuedByVendorCA(admin, this.confAlias, extraCert)) { this.errorMessage = "The certificate in extraCert field is not issued by any of the configured Vendor CAs: " + cmpConfiguration.getVendorCA(confAlias); return false; } // Extract the username from extraCert to use for further authentication String subjectDN = CertTools.getSubjectDN(extraCert); extraCertUsername = CertTools.getPartFromDN(subjectDN, this.cmpConfiguration.getExtractUsernameComponent(this.confAlias)); if (log.isDebugEnabled()) { log.debug("Username (" + extraCertUsername + ") was extracted from the '" + this.cmpConfiguration.getExtractUsernameComponent(this.confAlias) + "' part of the subjectDN of the certificate in the 'extraCerts' field."); } } else { // Get the CA to use for the authentication CAInfo cainfo = getCAInfoByIssuer(CertTools.getIssuerDN(extraCert)); // Check that extraCert is in the Database CertificateInfo certinfo = certSession .getCertificateInfo(CertTools.getFingerprintAsString(extraCert)); if (certinfo == null) { this.errorMessage = "The certificate attached to the PKIMessage in the extraCert field could not be found in the database."; return false; } // More extraCert verifications if (!isExtraCertIssuedByCA(cainfo) || !isExtraCertValid() || !isExtraCertActive(certinfo)) { return false; } // Extract the username from extraCert to use for further authentication extraCertUsername = certinfo.getUsername(); } // Check if this certificate belongs to the user if ((username != null) && (extraCertUsername != null)) { if (!StringUtils.equals(username, extraCertUsername)) { this.errorMessage = "The End Entity certificate attached to the PKIMessage in the extraCert field does not belong to user '" + username + "'"; if (log.isDebugEnabled()) { // Use a different debug message, as not to reveal too much information log.debug(this.errorMessage + ", but to user '" + extraCertUsername + "'"); } return false; } //set the password of the request to this user's password so it can later be used when issuing the certificate if (log.isDebugEnabled()) { log.debug( "The End Entity certificate attached to the PKIMessage in the extraCert field belongs to user '" + username + "'."); log.debug("Extracting and setting password for user '" + username + "'."); } try { EndEntityInformation user = eeAccessSession.findUser(admin, username); password = user.getPassword(); if (password == null) { password = genRandomPwd(); user.setPassword(password); eeManagementSession.changeUser(admin, user, false); } } catch (AuthorizationDeniedException e) { if (log.isDebugEnabled()) { log.debug(e.getLocalizedMessage()); } this.errorMessage = e.getLocalizedMessage(); return false; } catch (CADoesntExistsException e) { if (log.isDebugEnabled()) { log.debug(e.getLocalizedMessage()); } this.errorMessage = e.getLocalizedMessage(); return false; } catch (UserDoesntFullfillEndEntityProfile e) { if (log.isDebugEnabled()) { log.debug(e.getLocalizedMessage()); } this.errorMessage = e.getLocalizedMessage(); return false; } catch (WaitingForApprovalException e) { if (log.isDebugEnabled()) { log.debug(e.getLocalizedMessage()); } this.errorMessage = e.getLocalizedMessage(); return false; } catch (EjbcaException e) { if (log.isDebugEnabled()) { log.debug(e.getLocalizedMessage()); } this.errorMessage = e.getLocalizedMessage(); return false; } } } //------------------------------------------------------------- //Begin the signature verification process. //Verify the signature of msg using the public key of extraCert //------------------------------------------------------------- try { final Signature sig = Signature.getInstance(msg.getHeader().getProtectionAlg().getAlgorithm().getId(), "BC"); sig.initVerify(extraCert.getPublicKey()); sig.update(CmpMessageHelper.getProtectedBytes(msg)); if (sig.verify(msg.getProtection().getBytes())) { if (password == null) { // If not set earlier password = genRandomPwd(); } } else { this.errorMessage = "Failed to verify the signature in the PKIMessage"; return false; } } catch (InvalidKeyException e) { if (log.isDebugEnabled()) { log.debug(e.getLocalizedMessage()); } this.errorMessage = e.getLocalizedMessage(); return false; } catch (NoSuchAlgorithmException e) { if (log.isDebugEnabled()) { log.debug(e.getLocalizedMessage()); } this.errorMessage = e.getLocalizedMessage(); return false; } catch (NoSuchProviderException e) { if (log.isDebugEnabled()) { log.debug(e.getLocalizedMessage()); } this.errorMessage = e.getLocalizedMessage(); return false; } catch (SignatureException e) { if (log.isDebugEnabled()) { log.debug(e.getLocalizedMessage()); } this.errorMessage = e.getLocalizedMessage(); return false; } return this.password != null; }
From source file:org.ejbca.core.protocol.cmp.authentication.HMACAuthenticationModule.java
License:Open Source License
@Override /*/*ww w .ja v a 2s . c o m*/ * Verifies that 'msg' is sent by a trusted source. * * In RA mode: * - A globally configured shared secret for all CAs will be used to authenticate the message. * - If the globally shared secret fails, the password set in the CA will be used to authenticate the message. * In client mode, the clear-text password set in the pre-registered end entity in the database will be used to * authenticate the message. * * When successful, the authentication string will be set to the password that was successfully used in authenticating the message. */ public boolean verifyOrExtract(final PKIMessage msg, final String username) { if (msg == null) { this.errorMessage = "No PKIMessage was found"; return false; } if ((msg.getProtection() == null) || (msg.getHeader().getProtectionAlg() == null)) { this.errorMessage = "PKI Message is not athenticated properly. No HMAC protection was found."; return false; } try { verifyer = new CmpPbeVerifyer(msg); } catch (Exception e) { this.errorMessage = "Could not create CmpPbeVerifyer. " + e.getMessage(); return false; } if (verifyer == null) { this.errorMessage = "Could not create CmpPbeVerifyer Object"; return false; } if (this.cmpConfiguration.getRAMode(this.confAlias)) { //RA mode if (LOG.isDebugEnabled()) { LOG.debug("Verifying HMAC in RA mode"); } // Check that the value of KeyId from the request is allowed // Note that this restriction only applies to HMAC and not EndEntityCertificate because in the later, the use of profiles can be restricted through // Administrator privileges. Other authentication modules are not used in RA mode if (StringUtils.equals(cmpConfiguration.getRAEEProfile(confAlias), "KeyId") || StringUtils.equals(cmpConfiguration.getRACertProfile(confAlias), "KeyId")) { final String keyId = CmpMessageHelper.getStringFromOctets(msg.getHeader().getSenderKID()); if (StringUtils.equals(keyId, "EMPTY") || StringUtils.equals(keyId, "ENDUSER")) { errorMessage = "Unaccepted KeyId '" + keyId + "' in CMP request"; LOG.info(errorMessage); return false; } } // If we use a globally configured shared secret for all CAs we check it right away String authSecret = globalSharedSecret; if (globalSharedSecret != null) { if (LOG.isDebugEnabled()) { LOG.debug("Verifying message using Global Shared secret"); } try { if (verifyer.verify(authSecret)) { this.password = authSecret; } else { String errmsg = INTRES.getLocalizedMessage("cmp.errorauthmessage", "Global auth secret"); LOG.info(errmsg); // info because this is something we should expect and we handle it if (verifyer.getErrMsg() != null) { errmsg = verifyer.getErrMsg(); LOG.info(errmsg); } } } catch (InvalidKeyException e) { this.errorMessage = e.getLocalizedMessage(); if (LOG.isDebugEnabled()) { LOG.debug(this.errorMessage, e); } return false; } catch (NoSuchAlgorithmException e) { this.errorMessage = e.getLocalizedMessage(); if (LOG.isDebugEnabled()) { LOG.debug(this.errorMessage, e); } return false; } catch (NoSuchProviderException e) { this.errorMessage = e.getLocalizedMessage(); if (LOG.isDebugEnabled()) { LOG.debug(this.errorMessage, e); } return false; } } // If password is null, then we failed verification using global shared secret if (this.password == null) { if (cainfo instanceof X509CAInfo) { authSecret = ((X509CAInfo) cainfo).getCmpRaAuthSecret(); if (StringUtils.isNotEmpty(authSecret)) { if (LOG.isDebugEnabled()) { LOG.debug("Verify message using 'CMP RA Authentication Secret' from CA '" + cainfo.getName() + "'."); } try { if (verifyer.verify(authSecret)) { this.password = authSecret; } else { // info because this is something we should expect and we handle it LOG.info(INTRES.getLocalizedMessage("cmp.errorauthmessage", "Auth secret for CA=" + cainfo.getName())); if (verifyer.getErrMsg() != null) { LOG.info(verifyer.getErrMsg()); } } } catch (InvalidKeyException e) { this.errorMessage = INTRES.getLocalizedMessage("cmp.errorgeneral"); LOG.error(this.errorMessage, e); return false; } catch (NoSuchAlgorithmException e) { this.errorMessage = INTRES.getLocalizedMessage("cmp.errorgeneral"); LOG.error(this.errorMessage, e); return false; } catch (NoSuchProviderException e) { this.errorMessage = INTRES.getLocalizedMessage("cmp.errorgeneral"); LOG.error(this.errorMessage, e); return false; } } else { if (LOG.isDebugEnabled()) { LOG.debug("CMP password is null from CA '" + cainfo.getName() + "'."); } } } } // If password is still null, then we have failed verification with CA authentication secret too. if (password == null) { this.errorMessage = "Failed to verify message using both Global Shared Secret and CMP RA Authentication Secret"; return false; } } else { //client mode if (LOG.isDebugEnabled()) { LOG.debug("Verifying HMAC in Client mode"); } //If client mode, we try to get the pre-registered endentity from the DB, and if there is a //clear text password we check HMAC using this password. EndEntityInformation userdata = null; String subjectDN = null; try { if (username != null) { if (LOG.isDebugEnabled()) { LOG.debug("Searching for an end entity with username='" + username + "'."); } userdata = this.eeAccessSession.findUser(admin, username); } else { // No username given, so we try to find from subject/issuerDN from the certificate request final CertTemplate certTemp = getCertTemplate(msg); subjectDN = certTemp.getSubject().toString(); String issuerDN = null; final X500Name issuer = certTemp.getIssuer(); if ((issuer != null) && (subjectDN != null)) { issuerDN = issuer.toString(); if (LOG.isDebugEnabled()) { LOG.debug("Searching for an end entity with SubjectDN='" + subjectDN + "' and isserDN='" + issuerDN + "'"); } List<EndEntityInformation> userdataList = eeAccessSession .findUserBySubjectAndIssuerDN(this.admin, subjectDN, issuerDN); userdata = userdataList.get(0); if (userdataList.size() > 1) { LOG.warn("Multiple end entities with subject DN " + subjectDN + " and issuer DN" + issuerDN + " were found. This may lead to unexpected behavior."); } } else if (subjectDN != null) { if (LOG.isDebugEnabled()) { LOG.debug("Searching for an end entity with SubjectDN='" + subjectDN + "'."); } List<EndEntityInformation> userdataList = this.eeAccessSession.findUserBySubjectDN(admin, subjectDN); if (userdataList.size() > 0) { userdata = userdataList.get(0); } if (userdataList.size() > 1) { LOG.warn("Multiple end entities with subject DN " + subjectDN + " were found. This may lead to unexpected behavior."); } } } } catch (AuthorizationDeniedException e) { LOG.info("No EndEntity with subjectDN '" + subjectDN + "' could be found. " + e.getLocalizedMessage()); } if (userdata != null) { if (LOG.isDebugEnabled()) { LOG.debug("Comparing HMAC password authentication for user '" + userdata.getUsername() + "'."); } final String eepassword = userdata.getPassword(); if (StringUtils.isNotEmpty(eepassword)) { try { if (verifyer.verify(eepassword)) { this.password = eepassword; } else { String errmsg = INTRES.getLocalizedMessage("cmp.errorauthmessage", userdata.getUsername()); LOG.info(errmsg); // info because this is something we should expect and we handle it if (verifyer.getErrMsg() != null) { errmsg = verifyer.getErrMsg(); LOG.info(errmsg); } this.errorMessage = errmsg; return false; } } catch (InvalidKeyException e) { this.errorMessage = INTRES.getLocalizedMessage("cmp.errorgeneral"); LOG.error(this.errorMessage, e); return false; } catch (NoSuchAlgorithmException e) { this.errorMessage = INTRES.getLocalizedMessage("cmp.errorgeneral"); LOG.error(this.errorMessage, e); return false; } catch (NoSuchProviderException e) { this.errorMessage = INTRES.getLocalizedMessage("cmp.errorgeneral"); LOG.error(this.errorMessage, e); return false; } } else { this.errorMessage = "No clear text password for user '" + userdata.getUsername() + "', not possible to check authentication."; return false; } } else { LOG.info(INTRES.getLocalizedMessage("ra.errorentitynotexist", StringUtils.isNotEmpty(username) ? username : subjectDN)); this.errorMessage = INTRES.getLocalizedMessage("ra.wrongusernameorpassword"); return false; } } return this.password != null; }
From source file:org.ejbca.core.protocol.cmp.AuthenticationModulesTest.java
License:Open Source License
@Test public void test05EECrmfReq() throws NoSuchAlgorithmException, EjbcaException, IOException, Exception { this.cmpConfiguration.setAuthenticationModule(ALIAS, CmpConfiguration.AUTHMODULE_ENDENTITY_CERTIFICATE); this.cmpConfiguration.setAuthenticationParameters(ALIAS, "TestCA"); this.cmpConfiguration.setRAMode(ALIAS, true); this.globalConfigurationSession.saveConfiguration(ADMIN, this.cmpConfiguration); final X500Name testUserDN = new X500Name("CN=cmptestuser5,C=SE"); final String testUsername = "cmptestuser5"; String fingerprint = null;/*from w w w. j av a 2 s.c o m*/ String fingerprint2 = null; AuthenticationToken admToken = null; Certificate admCert = null; try { KeyPair keys = KeyTools.genKeys("512", AlgorithmConstants.KEYALGORITHM_RSA); AlgorithmIdentifier pAlg = new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption); PKIMessage msg = genCertReq(issuerDN, testUserDN, keys, this.cacert, this.nonce, this.transid, false, null, null, null, null, pAlg, new DEROctetString(this.nonce)); assertNotNull("Generating CrmfRequest failed.", msg); KeyPair admkeys = KeyTools.genKeys("512", "RSA"); admToken = createAdminToken(admkeys, testUsername, testUserDN.toString(), this.caid, SecConst.EMPTY_ENDENTITYPROFILE, CertificateProfileConstants.CERTPROFILE_FIXED_ENDUSER); admCert = getCertFromCredentials(admToken); fingerprint = CertTools.getFingerprintAsString(admCert); CMPCertificate[] extraCert = getCMPCert(admCert); msg = CmpMessageHelper.buildCertBasedPKIProtection(msg, extraCert, admkeys.getPrivate(), pAlg.getAlgorithm().getId(), "BC"); assertNotNull(msg); //******************************************'''''' final Signature sig = Signature.getInstance(msg.getHeader().getProtectionAlg().getAlgorithm().getId(), "BC"); sig.initVerify(admCert.getPublicKey()); sig.update(CmpMessageHelper.getProtectedBytes(msg)); boolean verified = sig.verify(msg.getProtection().getBytes()); assertTrue("Signing the message failed.", verified); //*************************************************** final ByteArrayOutputStream bao = new ByteArrayOutputStream(); final DEROutputStream out = new DEROutputStream(bao); out.writeObject(msg); final byte[] ba = bao.toByteArray(); // Send request and receive response final byte[] resp = sendCmpHttp(ba, 200, ALIAS); checkCmpResponseGeneral(resp, issuerDN, testUserDN, this.cacert, msg.getHeader().getSenderNonce().getOctets(), msg.getHeader().getTransactionID().getOctets(), true, null, PKCSObjectIdentifiers.sha1WithRSAEncryption.getId()); CertReqMessages ir = (CertReqMessages) msg.getBody().getContent(); Certificate cert2 = checkCmpCertRepMessage(testUserDN, this.cacert, resp, ir.toCertReqMsgArray()[0].getCertReq().getCertReqId().getValue().intValue()); assertNotNull("CrmfRequest did not return a certificate", cert2); fingerprint2 = CertTools.getFingerprintAsString(cert2); } finally { removeAuthenticationToken(admToken, admCert, testUsername); // also removes testUsername this.internalCertStoreSession.removeCertificate(fingerprint); this.internalCertStoreSession.removeCertificate(fingerprint2); } }
From source file:org.ejbca.core.protocol.cmp.AuthenticationModulesTest.java
License:Open Source License
@Test public void test08EECrmfReqMultipleAuthModules() throws NoSuchAlgorithmException, EjbcaException, IOException, Exception { String modules = CmpConfiguration.AUTHMODULE_HMAC + ";" + CmpConfiguration.AUTHMODULE_ENDENTITY_CERTIFICATE; String parameters = "foo123" + ";" + "TestCA"; this.cmpConfiguration.setAuthenticationModule(ALIAS, modules); this.cmpConfiguration.setAuthenticationParameters(ALIAS, parameters); this.cmpConfiguration.setRAMode(ALIAS, true); this.globalConfigurationSession.saveConfiguration(ADMIN, this.cmpConfiguration); KeyPair keys = KeyTools.genKeys("512", AlgorithmConstants.KEYALGORITHM_RSA); AlgorithmIdentifier pAlg = new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption); PKIMessage msg = genCertReq(issuerDN, USER_DN, keys, this.cacert, this.nonce, this.transid, false, null, null, null, null, pAlg, null); assertNotNull("Generating CrmfRequest failed.", msg); String adminName = "cmpTestAdmin"; KeyPair admkeys = KeyTools.genKeys("1024", "RSA"); AuthenticationToken adminToken = createAdminToken(admkeys, adminName, "CN=" + adminName + ",C=SE", this.caid, SecConst.EMPTY_ENDENTITYPROFILE, CertificateProfileConstants.CERTPROFILE_FIXED_ENDUSER); Certificate admCert = getCertFromCredentials(adminToken); CMPCertificate[] extraCert = getCMPCert(admCert); msg = CmpMessageHelper.buildCertBasedPKIProtection(msg, extraCert, admkeys.getPrivate(), pAlg.getAlgorithm().getId(), "BC"); assertNotNull(msg);/*from www . j ava 2s .c o m*/ //******************************************** final Signature sig = Signature.getInstance(msg.getHeader().getProtectionAlg().getAlgorithm().getId(), "BC"); sig.initVerify(admCert.getPublicKey()); sig.update(CmpMessageHelper.getProtectedBytes(msg)); boolean verified = sig.verify(msg.getProtection().getBytes()); assertTrue("Signing the message failed.", verified); //******************************************** final ByteArrayOutputStream bao = new ByteArrayOutputStream(); final DEROutputStream out = new DEROutputStream(bao); out.writeObject(msg); final byte[] ba = bao.toByteArray(); // Send request and receive response final byte[] resp = sendCmpHttp(ba, 200, ALIAS); checkCmpResponseGeneral(resp, issuerDN, USER_DN, this.cacert, msg.getHeader().getSenderNonce().getOctets(), msg.getHeader().getTransactionID().getOctets(), true, null, PKCSObjectIdentifiers.sha1WithRSAEncryption.getId()); CertReqMessages ir = (CertReqMessages) msg.getBody().getContent(); Certificate cert2 = checkCmpCertRepMessage(USER_DN, this.cacert, resp, ir.toCertReqMsgArray()[0].getCertReq().getCertReqId().getValue().intValue()); assertNotNull("CrmfRequest did not return a certificate", cert2); removeAuthenticationToken(adminToken, admCert, adminName); }
From source file:org.ejbca.core.protocol.cmp.AuthenticationModulesTest.java
License:Open Source License
@Test public void test12EECrmfNotCheckAdmin() throws NoSuchAlgorithmException, EjbcaException, IOException, Exception { this.cmpConfiguration.setAuthenticationModule(ALIAS, CmpConfiguration.AUTHMODULE_ENDENTITY_CERTIFICATE); this.cmpConfiguration.setAuthenticationParameters(ALIAS, "TestCA"); this.cmpConfiguration.setOmitVerificationsInECC(ALIAS, true); this.cmpConfiguration.setRAMode(ALIAS, true); this.globalConfigurationSession.saveConfiguration(ADMIN, this.cmpConfiguration); KeyPair keys = KeyTools.genKeys("512", AlgorithmConstants.KEYALGORITHM_RSA); AlgorithmIdentifier pAlg = new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption); PKIMessage msg = genCertReq(issuerDN, USER_DN, keys, this.cacert, this.nonce, this.transid, false, null, null, null, null, pAlg, new DEROctetString(this.nonce)); assertNotNull("Generating CrmfRequest failed.", msg); String adminName = "cmpTestAdmin"; KeyPair admkeys = KeyTools.genKeys("1024", "RSA"); AuthenticationToken adminToken = createAdminToken(admkeys, adminName, "CN=" + adminName + ",C=SE", this.caid, SecConst.EMPTY_ENDENTITYPROFILE, CertificateProfileConstants.CERTPROFILE_FIXED_ENDUSER); Certificate admCert = getCertFromCredentials(adminToken); CMPCertificate[] extraCert = getCMPCert(admCert); msg = CmpMessageHelper.buildCertBasedPKIProtection(msg, extraCert, admkeys.getPrivate(), pAlg.getAlgorithm().getId(), "BC"); assertNotNull(msg);//from w w w .j a v a 2 s . c o m //******************************************** final Signature sig = Signature.getInstance(msg.getHeader().getProtectionAlg().getAlgorithm().getId(), "BC"); sig.initVerify(admCert.getPublicKey()); sig.update(CmpMessageHelper.getProtectedBytes(msg)); boolean verified = sig.verify(msg.getProtection().getBytes()); assertTrue("Signing the message failed.", verified); //******************************************** final ByteArrayOutputStream bao = new ByteArrayOutputStream(); final DEROutputStream out = new DEROutputStream(bao); out.writeObject(msg); final byte[] ba = bao.toByteArray(); // Send request and receive response final byte[] resp = sendCmpHttp(ba, 200, ALIAS); checkCmpResponseGeneral(resp, issuerDN, USER_DN, this.cacert, msg.getHeader().getSenderNonce().getOctets(), msg.getHeader().getTransactionID().getOctets(), false, null, PKCSObjectIdentifiers.sha1WithRSAEncryption.getId()); ASN1InputStream inputStream = new ASN1InputStream(new ByteArrayInputStream(resp)); try { PKIMessage respObject = PKIMessage.getInstance(inputStream.readObject()); assertNotNull(respObject); PKIBody body = respObject.getBody(); assertEquals(23, body.getType()); ErrorMsgContent err = (ErrorMsgContent) body.getContent(); String errMsg = err.getPKIStatusInfo().getStatusString().getStringAt(0).getString(); String expectedErrmsg = "Omitting some verifications can only be accepted in RA mode and when the CMP request has already been authenticated, for example, through the use of NestedMessageContent"; assertEquals(expectedErrmsg, errMsg); } finally { inputStream.close(); } removeAuthenticationToken(adminToken, admCert, adminName); }
From source file:org.ejbca.core.protocol.cmp.AuthenticationModulesTest.java
License:Open Source License
/** Test CMP initial request against EJBCA CMP in client mode (operationmode=normal) using End Entity certificate signature authentication, * i.e. the request is signed by a certificate of the same end entity making the request, and this signature is used for authenticating the end entity. * Test:/*w ww .j av a2 s .c o m*/ * - Request signed by a fake certificate, i.e. one that is not in the database (FAIL) * - Request signed by a certificate that beloongs to another user (FAIL) * - Request signed by a proper certificate but where user status is not NEW (FAIL) * - Request signed by a proper, but revoked certificate (FAIL) * - A working request signed by a proper, unrevoked certificate and user status is NEW (SUCCESS) * * @throws Exception on some errors */ @Test public void test18CrmfReqClientModeEESignature() throws Exception { this.cmpConfiguration.setAuthenticationModule(ALIAS, CmpConfiguration.AUTHMODULE_ENDENTITY_CERTIFICATE); this.cmpConfiguration.setAuthenticationParameters(ALIAS, "-"); this.cmpConfiguration.setRAMode(ALIAS, false); this.globalConfigurationSession.saveConfiguration(ADMIN, this.cmpConfiguration); final X500Name testUserDN = new X500Name("CN=cmptestuser16,C=SE"); final String testUsername = "cmptestuser16"; final String otherUserDN = "CN=cmptestotheruser16,C=SE"; final String otherUsername = "cmptestotheruser16"; String fingerprint = null; String fingerprint2 = null; String fingerprint3 = null; try { KeyPair keys = KeyTools.genKeys("512", AlgorithmConstants.KEYALGORITHM_RSA); KeyPair fakeKeys = KeyTools.genKeys("512", AlgorithmConstants.KEYALGORITHM_RSA); createUser(testUsername, testUserDN.toString(), "foo123", true, this.caid, SecConst.EMPTY_ENDENTITYPROFILE, CertificateProfileConstants.CERTPROFILE_FIXED_ENDUSER); // A real certificate that can be used to sign the message Certificate cert = this.signSession.createCertificate(ADMIN, testUsername, "foo123", new PublicKeyWrapper(keys.getPublic())); fingerprint = CertTools.getFingerprintAsString(cert); // A fake certificate that should not be valid Certificate fakeCert = CertTools.genSelfCert(testUserDN.toString(), 30, null, fakeKeys.getPrivate(), fakeKeys.getPublic(), AlgorithmConstants.SIGALG_SHA1_WITH_RSA, false); // Step 1 sign with fake certificate, should not be valid as end entity authentication { AlgorithmIdentifier pAlg = new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption); PKIMessage msg = genCertReq(issuerDN, testUserDN, keys, this.cacert, this.nonce, this.transid, false, null, null, null, null, pAlg, null); assertNotNull("Generating CrmfRequest failed.", msg); CMPCertificate[] extraCert = getCMPCert(fakeCert); msg = CmpMessageHelper.buildCertBasedPKIProtection(msg, extraCert, fakeKeys.getPrivate(), pAlg.getAlgorithm().getId(), "BC"); assertNotNull(msg); //******************************************'''''' final Signature sig = Signature .getInstance(msg.getHeader().getProtectionAlg().getAlgorithm().getId(), "BC"); sig.initVerify(fakeCert.getPublicKey()); sig.update(CmpMessageHelper.getProtectedBytes(msg)); boolean verified = sig.verify(msg.getProtection().getBytes()); assertTrue("Signing the message failed.", verified); //*************************************************** final ByteArrayOutputStream bao = new ByteArrayOutputStream(); final DEROutputStream out = new DEROutputStream(bao); out.writeObject(msg); final byte[] ba = bao.toByteArray(); // Send request and receive response final byte[] resp = sendCmpHttp(ba, 200, ALIAS); // This should have failed checkCmpResponseGeneral(resp, issuerDN, testUserDN, this.cacert, msg.getHeader().getSenderNonce().getOctets(), msg.getHeader().getTransactionID().getOctets(), false, null, PKCSObjectIdentifiers.sha1WithRSAEncryption.getId()); ASN1InputStream inputStream = new ASN1InputStream(new ByteArrayInputStream(resp)); PKIMessage respObject = PKIMessage.getInstance(inputStream.readObject()); try { assertNotNull(respObject); PKIBody body = respObject.getBody(); assertEquals(23, body.getType()); ErrorMsgContent err = (ErrorMsgContent) body.getContent(); String errMsg = err.getPKIStatusInfo().getStatusString().getStringAt(0).getString(); String expectedErrMsg = "The certificate attached to the PKIMessage in the extraCert field could not be found in the database."; assertEquals(expectedErrMsg, errMsg); } finally { inputStream.close(); } } // Step 2, sign the request with a certificate that does not belong to the user { KeyPair otherKeys = KeyTools.genKeys("512", AlgorithmConstants.KEYALGORITHM_RSA); createUser(otherUsername, otherUserDN, "foo123", true, this.caid, SecConst.EMPTY_ENDENTITYPROFILE, CertificateProfileConstants.CERTPROFILE_FIXED_ENDUSER); // A real certificate that can be used to sign the message Certificate othercert = this.signSession.createCertificate(ADMIN, otherUsername, "foo123", new PublicKeyWrapper(otherKeys.getPublic())); fingerprint2 = CertTools.getFingerprintAsString(cert); AlgorithmIdentifier pAlg = new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption); PKIMessage msg = genCertReq(issuerDN, testUserDN, keys, this.cacert, this.nonce, this.transid, false, null, null, null, null, pAlg, null); assertNotNull("Generating CrmfRequest failed.", msg); CMPCertificate[] extraCert = getCMPCert(othercert); msg = CmpMessageHelper.buildCertBasedPKIProtection(msg, extraCert, otherKeys.getPrivate(), pAlg.getAlgorithm().getId(), "BC"); assertNotNull(msg); //******************************************'''''' final Signature sig = Signature .getInstance(msg.getHeader().getProtectionAlg().getAlgorithm().getId(), "BC"); sig.initVerify(othercert.getPublicKey()); sig.update(CmpMessageHelper.getProtectedBytes(msg)); boolean verified = sig.verify(msg.getProtection().getBytes()); assertTrue("Signing the message failed.", verified); //*************************************************** final ByteArrayOutputStream bao = new ByteArrayOutputStream(); final DEROutputStream out = new DEROutputStream(bao); out.writeObject(msg); final byte[] ba = bao.toByteArray(); // Send request and receive response final byte[] resp = sendCmpHttp(ba, 200, ALIAS); // This should have failed checkCmpResponseGeneral(resp, issuerDN, testUserDN, this.cacert, msg.getHeader().getSenderNonce().getOctets(), msg.getHeader().getTransactionID().getOctets(), false, null, PKCSObjectIdentifiers.sha1WithRSAEncryption.getId()); ASN1InputStream inputStream = new ASN1InputStream(new ByteArrayInputStream(resp)); try { PKIMessage respObject = PKIMessage.getInstance(inputStream.readObject()); assertNotNull(respObject); PKIBody body = respObject.getBody(); assertEquals(23, body.getType()); ErrorMsgContent err = (ErrorMsgContent) body.getContent(); String errMsg = err.getPKIStatusInfo().getStatusString().getStringAt(0).getString(); String expectedErrMsg = "The End Entity certificate attached to the PKIMessage in the extraCert field does not belong to user '" + testUsername + "'"; assertEquals(expectedErrMsg, errMsg); } finally { inputStream.close(); } } // Step 3 sign with the real certificate, but user status is not NEW AlgorithmIdentifier pAlg = new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption); PKIMessage msg = genCertReq(issuerDN, testUserDN, keys, this.cacert, this.nonce, this.transid, false, null, null, null, null, pAlg, null); assertNotNull("Generating CrmfRequest failed.", msg); CMPCertificate[] extraCert = getCMPCert(cert); msg = CmpMessageHelper.buildCertBasedPKIProtection(msg, extraCert, keys.getPrivate(), pAlg.getAlgorithm().getId(), "BC"); assertNotNull(msg); //******************************************'''''' final Signature sig = Signature.getInstance(msg.getHeader().getProtectionAlg().getAlgorithm().getId(), "BC"); sig.initVerify(cert.getPublicKey()); sig.update(CmpMessageHelper.getProtectedBytes(msg)); boolean verified = sig.verify(msg.getProtection().getBytes()); assertTrue("Signing the message failed.", verified); //*************************************************** final ByteArrayOutputStream bao = new ByteArrayOutputStream(); final DEROutputStream out = new DEROutputStream(bao); out.writeObject(msg); final byte[] ba = bao.toByteArray(); // Send request and receive response final byte[] resp = sendCmpHttp(ba, 200, ALIAS); checkCmpResponseGeneral(resp, issuerDN, testUserDN, this.cacert, msg.getHeader().getSenderNonce().getOctets(), msg.getHeader().getTransactionID().getOctets(), false, null, PKCSObjectIdentifiers.sha1WithRSAEncryption.getId()); // This should have failed ASN1InputStream inputStream = new ASN1InputStream(new ByteArrayInputStream(resp)); try { PKIMessage respObject = PKIMessage.getInstance(inputStream.readObject()); assertNotNull(respObject); PKIBody body = respObject.getBody(); assertEquals(23, body.getType()); ErrorMsgContent err = (ErrorMsgContent) body.getContent(); String errMsg = err.getPKIStatusInfo().getStatusString().getStringAt(0).getString(); String expectedErrMsg = "Got request with status GENERATED (40), NEW, FAILED or INPROCESS required: cmptestuser16."; assertEquals(expectedErrMsg, errMsg); // Step 4 now set status to NEW, and a clear text password, then it should finally work createUser(testUsername, testUserDN.toString(), "randompasswordhere", true, this.caid, SecConst.EMPTY_ENDENTITYPROFILE, CertificateProfileConstants.CERTPROFILE_FIXED_ENDUSER); // Send request and receive response final byte[] resp2 = sendCmpHttp(ba, 200, ALIAS); CertReqMessages ir = (CertReqMessages) msg.getBody().getContent(); Certificate cert2 = checkCmpCertRepMessage(testUserDN, this.cacert, resp2, ir.toCertReqMsgArray()[0].getCertReq().getCertReqId().getValue().intValue()); assertNotNull("CrmfRequest did not return a certificate", cert2); fingerprint3 = CertTools.getFingerprintAsString(cert2); // Step 5, revoke the certificate and try again { this.certificateStoreSession.setRevokeStatus(ADMIN, cert, RevokedCertInfo.REVOCATION_REASON_CESSATIONOFOPERATION, null); final byte[] resp3 = sendCmpHttp(ba, 200, ALIAS); // This should have failed checkCmpResponseGeneral(resp, issuerDN, testUserDN, this.cacert, msg.getHeader().getSenderNonce().getOctets(), msg.getHeader().getTransactionID().getOctets(), false, null, PKCSObjectIdentifiers.sha1WithRSAEncryption.getId()); ASN1InputStream inputStream3 = new ASN1InputStream(new ByteArrayInputStream(resp3)); try { PKIMessage respObject3 = PKIMessage.getInstance(inputStream3.readObject()); assertNotNull(respObject); PKIBody body3 = respObject3.getBody(); assertEquals(23, body3.getType()); err = (ErrorMsgContent) body3.getContent(); String errMsg3 = err.getPKIStatusInfo().getStatusString().getStringAt(0).getString(); String expectedErrMsg3 = "The certificate attached to the PKIMessage in the extraCert field is not active."; assertEquals(expectedErrMsg3, errMsg3); } finally { inputStream3.close(); } } } finally { inputStream.close(); } } finally { try { this.endEntityManagementSession.revokeAndDeleteUser(ADMIN, testUsername, ReasonFlags.unused); } catch (Exception e) {// do nothing } try { this.endEntityManagementSession.revokeAndDeleteUser(ADMIN, otherUsername, ReasonFlags.unused); } catch (Exception e) {// do nothing } this.internalCertStoreSession.removeCertificate(fingerprint); this.internalCertStoreSession.removeCertificate(fingerprint2); this.internalCertStoreSession.removeCertificate(fingerprint3); } }
From source file:org.ejbca.core.protocol.cmp.AuthenticationModulesTest.java
License:Open Source License
/** * Tests that EndEntityAuthentication module can be successfully used in client mode when the end entity's password is not stored in clear text. * /*from w w w . j av a 2 s . co m*/ * @throws Exception */ @Test public void test21CrmfRequestClientModeEECNotClearPassword() throws Exception { this.cmpConfiguration.setAuthenticationModule(ALIAS, CmpConfiguration.AUTHMODULE_ENDENTITY_CERTIFICATE); this.cmpConfiguration.setAuthenticationParameters(ALIAS, "-"); this.cmpConfiguration.setRAMode(ALIAS, false); this.globalConfigurationSession.saveConfiguration(ADMIN, this.cmpConfiguration); final X500Name testUserDN = new X500Name("CN=cmptestuser21,C=SE"); final String testUsername = "cmptestuser21"; String fingerprint = null; String fingerprint2 = null; try { KeyPair keys = KeyTools.genKeys("512", AlgorithmConstants.KEYALGORITHM_RSA); AlgorithmIdentifier pAlg = new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption); createUser(testUsername, testUserDN.toString(), "foo123", false, this.caid, SecConst.EMPTY_ENDENTITYPROFILE, CertificateProfileConstants.CERTPROFILE_FIXED_ENDUSER); Certificate cert = this.signSession.createCertificate(ADMIN, testUsername, "foo123", new PublicKeyWrapper(keys.getPublic())); fingerprint = CertTools.getFingerprintAsString(cert); //Edit the status of the user to NEW createUser(testUsername, testUserDN.toString(), "foo123", false, this.caid, SecConst.EMPTY_ENDENTITYPROFILE, CertificateProfileConstants.CERTPROFILE_FIXED_ENDUSER); PKIMessage msg = genCertReq(issuerDN, testUserDN, keys, this.cacert, this.nonce, this.transid, false, null, null, null, null, pAlg, null); assertNotNull("Generating CrmfRequest failed.", msg); CMPCertificate[] extraCert = getCMPCert(cert); msg = CmpMessageHelper.buildCertBasedPKIProtection(msg, extraCert, keys.getPrivate(), pAlg.getAlgorithm().getId(), "BC"); assertNotNull(msg); //******************************************'''''' final Signature sig = Signature.getInstance(msg.getHeader().getProtectionAlg().getAlgorithm().getId(), "BC"); sig.initVerify(cert.getPublicKey()); sig.update(CmpMessageHelper.getProtectedBytes(msg)); boolean verified = sig.verify(msg.getProtection().getBytes()); assertTrue("Signing the message failed.", verified); //*************************************************** final ByteArrayOutputStream bao = new ByteArrayOutputStream(); final DEROutputStream out = new DEROutputStream(bao); out.writeObject(msg); final byte[] ba = bao.toByteArray(); // Send request and receive response final byte[] resp = sendCmpHttp(ba, 200, ALIAS); CertReqMessages ir = (CertReqMessages) msg.getBody().getContent(); Certificate cert2 = checkCmpCertRepMessage(testUserDN, this.cacert, resp, ir.toCertReqMsgArray()[0].getCertReq().getCertReqId().getValue().intValue()); assertNotNull("CrmfRequest did not return a certificate", cert2); fingerprint2 = CertTools.getFingerprintAsString(cert2); } finally { try { this.endEntityManagementSession.revokeAndDeleteUser(ADMIN, testUsername, ReasonFlags.unused); } catch (Exception e) {// do nothing } this.internalCertStoreSession.removeCertificate(fingerprint); this.internalCertStoreSession.removeCertificate(fingerprint2); } }
From source file:org.ejbca.core.protocol.cmp.CmpMessageHelper.java
License:Open Source License
/** verifies signature protection on CMP PKI messages * //from ww w. j ava 2 s . c om * @param pKIMessage the CMP message to verify signature on, if protected by signature protection * @param pubKey the public key used to verify the signature * @return true if verification is ok or false if verification fails * @throws NoSuchAlgorithmException message is signed by an unknown algorithm * @throws NoSuchProviderException the BouncyCastle (BC) provider is not installed * @throws InvalidKeyException pubKey is not valid for signature verification * @throws SignatureException if the passed-in signature is improperly encoded or of the wrong type, if this signature algorithm is unable to process the input data provided, etc. */ public static boolean verifyCertBasedPKIProtection(PKIMessage pKIMessage, PublicKey pubKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, SignatureException { AlgorithmIdentifier sigAlg = pKIMessage.getHeader().getProtectionAlg(); if (LOG.isDebugEnabled()) { LOG.debug("Verifying signature with algorithm: " + sigAlg.getAlgorithm().getId()); } Signature sig = Signature.getInstance(sigAlg.getAlgorithm().getId(), "BC"); sig.initVerify(pubKey); sig.update(CmpMessageHelper.getProtectedBytes(pKIMessage)); boolean result = sig.verify(pKIMessage.getProtection().getBytes()); if (LOG.isDebugEnabled()) { LOG.debug("Verification result: " + result); } return result; }
From source file:org.ejbca.core.protocol.cmp.CmpPbeVerifyer.java
License:Open Source License
public CmpPbeVerifyer(final PKIMessage msg) { final PKIHeader head = msg.getHeader(); protectedBytes = CmpMessageHelper.getProtectedBytes(msg); protection = msg.getProtection(); pAlg = head.getProtectionAlg();/*from ww w .ja v a2 s .co m*/ final ASN1ObjectIdentifier algId = pAlg.getAlgorithm(); if (!StringUtils.equals(algId.getId(), CMPObjectIdentifiers.passwordBasedMac.getId())) { final String errMsg = "Protection algorithm id expected '" + CMPObjectIdentifiers.passwordBasedMac.getId() + "' (passwordBasedMac) but was '" + algId.getId() + "'."; throw new IllegalArgumentException(errMsg); } final PBMParameter pp = PBMParameter.getInstance(pAlg.getParameters()); iterationCount = pp.getIterationCount().getPositiveValue().intValue(); final AlgorithmIdentifier owfAlg = pp.getOwf(); // Normal OWF alg is 1.3.14.3.2.26 - SHA1 owfOid = owfAlg.getAlgorithm().getId(); final AlgorithmIdentifier macAlg = pp.getMac(); // Normal mac alg is 1.3.6.1.5.5.8.1.2 - HMAC/SHA1 macOid = macAlg.getAlgorithm().getId(); if (LOG.isDebugEnabled()) { LOG.debug("Protection type is: " + algId.getId()); LOG.debug("Iteration count is: " + iterationCount); LOG.debug("Owf type is: " + owfOid); LOG.debug("Mac type is: " + macOid); } salt = pp.getSalt().getOctets(); //log.info("Salt: "+new String(salt)); }
From source file:org.ejbca.core.protocol.cmp.CmpTestCase.java
License:Open Source License
protected static void checkCmpResponseGeneral(byte[] retMsg, String issuerDN, X500Name userDN, Certificate cacert, byte[] senderNonce, byte[] transId, boolean signed, String pbeSecret, String expectedSignAlg)/*ww w .ja v a 2 s .c o m*/ throws IOException, InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException { assertNotNull("No response from server.", retMsg); assertTrue("Response was of 0 length.", retMsg.length > 0); boolean pbe = (pbeSecret != null); // // Parse response message // ASN1InputStream asn1InputStream = new ASN1InputStream(new ByteArrayInputStream(retMsg)); PKIMessage respObject = null; try { respObject = PKIMessage.getInstance(asn1InputStream.readObject()); } finally { asn1InputStream.close(); } assertNotNull(respObject); // The signer, i.e. the CA, check it's the right CA PKIHeader header = respObject.getHeader(); // Check that the message is signed with the correct digest alg if (StringUtils.isEmpty(expectedSignAlg)) { expectedSignAlg = PKCSObjectIdentifiers.sha1WithRSAEncryption.getId(); } // if cacert is ECDSA we should expect an ECDSA signature alg //if (AlgorithmTools.getSignatureAlgorithm(cacert).contains("ECDSA")) { // expectedSignAlg = X9ObjectIdentifiers.ecdsa_with_SHA1.getId(); //} else if(AlgorithmTools.getSignatureAlgorithm(cacert).contains("ECGOST3410")) { // expectedSignAlg = CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001.getId(); //} else if(AlgorithmTools.getSignatureAlgorithm(cacert).contains("DSTU4145")) { // expectedSignAlg = (new ASN1ObjectIdentifier(CesecoreConfiguration.getOidDstu4145())).getId(); //} if (signed) { AlgorithmIdentifier algId = header.getProtectionAlg(); assertNotNull( "Protection algorithm was null when expecting a signed response, this was propably an unprotected error message: " + header.getFreeText(), algId); assertEquals(expectedSignAlg, algId.getAlgorithm().getId()); } if (pbe) { AlgorithmIdentifier algId = header.getProtectionAlg(); assertNotNull( "Protection algorithm was null when expecting a pbe protected response, this was propably an unprotected error message: " + header.getFreeText(), algId); assertEquals("Protection algorithm id: " + algId.getAlgorithm().getId(), CMPObjectIdentifiers.passwordBasedMac.getId(), algId.getAlgorithm().getId()); // 1.2.840.113549.1.1.5 - SHA-1 with RSA Encryption } // Check that the signer is the expected CA assertEquals(header.getSender().getTagNo(), 4); X500Name expissuer = new X500Name(issuerDN); X500Name actissuer = new X500Name(header.getSender().getName().toString()); assertEquals(expissuer, actissuer); if (signed) { // Verify the signature byte[] protBytes = CmpMessageHelper.getProtectedBytes(respObject); DERBitString bs = respObject.getProtection(); Signature sig; try { sig = Signature.getInstance(expectedSignAlg, "BC"); sig.initVerify(cacert); sig.update(protBytes); boolean ret = sig.verify(bs.getBytes()); assertTrue(ret); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); assertTrue(false); } catch (NoSuchProviderException e) { e.printStackTrace(); assertTrue(false); } catch (InvalidKeyException e) { e.printStackTrace(); assertTrue(false); } catch (SignatureException e) { e.printStackTrace(); assertTrue(false); } } if (pbe) { ASN1OctetString os = header.getSenderKID(); assertNotNull(os); String keyId = CmpMessageHelper.getStringFromOctets(os); log.debug("Found a sender keyId: " + keyId); // Verify the PasswordBased protection of the message byte[] protectedBytes = CmpMessageHelper.getProtectedBytes(respObject); DERBitString protection = respObject.getProtection(); AlgorithmIdentifier pAlg = header.getProtectionAlg(); log.debug("Protection type is: " + pAlg.getAlgorithm().getId()); PBMParameter pp = PBMParameter.getInstance(pAlg.getParameters()); int iterationCount = pp.getIterationCount().getPositiveValue().intValue(); log.debug("Iteration count is: " + iterationCount); AlgorithmIdentifier owfAlg = pp.getOwf(); // Normal OWF alg is 1.3.14.3.2.26 - SHA1 log.debug("Owf type is: " + owfAlg.getAlgorithm().getId()); AlgorithmIdentifier macAlg = pp.getMac(); // Normal mac alg is 1.3.6.1.5.5.8.1.2 - HMAC/SHA1 log.debug("Mac type is: " + macAlg.getAlgorithm().getId()); byte[] salt = pp.getSalt().getOctets(); // log.info("Salt is: "+new String(salt)); byte[] raSecret = pbeSecret != null ? pbeSecret.getBytes() : new byte[0]; byte[] basekey = new byte[raSecret.length + salt.length]; System.arraycopy(raSecret, 0, basekey, 0, raSecret.length); for (int i = 0; i < salt.length; i++) { basekey[raSecret.length + i] = salt[i]; } // Construct the base key according to rfc4210, section 5.1.3.1 MessageDigest dig = MessageDigest.getInstance(owfAlg.getAlgorithm().getId(), BouncyCastleProvider.PROVIDER_NAME); for (int i = 0; i < iterationCount; i++) { basekey = dig.digest(basekey); dig.reset(); } // HMAC/SHA1 os normal 1.3.6.1.5.5.8.1.2 or 1.2.840.113549.2.7 String macOid = macAlg.getAlgorithm().getId(); Mac mac = Mac.getInstance(macOid, BouncyCastleProvider.PROVIDER_NAME); SecretKey key = new SecretKeySpec(basekey, macOid); mac.init(key); mac.reset(); mac.update(protectedBytes, 0, protectedBytes.length); byte[] out = mac.doFinal(); // My out should now be the same as the protection bits byte[] pb = protection.getBytes(); boolean ret = Arrays.equals(out, pb); assertTrue(ret); } // --SenderNonce // SenderNonce is something the server came up with, but it should be 16 // chars byte[] nonce = header.getSenderNonce().getOctets(); assertEquals(nonce.length, 16); // --Recipient Nonce // recipient nonce should be the same as we sent away as sender nonce nonce = header.getRecipNonce().getOctets(); assertEquals(new String(nonce), new String(senderNonce)); // --Transaction ID // transid should be the same as the one we sent nonce = header.getTransactionID().getOctets(); assertEquals(new String(nonce), new String(transId)); }