/** * Verify a message with password based MAC protection. * * @param pkMacBuilder MAC builder that can be used to construct the appropriate MacCalculator * @param password the MAC password * @return true if the passed in password and MAC builder verify the message, false otherwise. * @throws CMPException if algorithm not MAC based, or an exception is thrown verifying the MAC. */ public boolean verify(PKMACBuilder pkMacBuilder, char[] password) throws CMPException { if (!CMPObjectIdentifiers.passwordBasedMac.equals(pkiMessage.getHeader().getProtectionAlg().getAlgorithm())) { throw new CMPException("protection algorithm not mac based"); } try { pkMacBuilder.setParameters(PBMParameter.getInstance(pkiMessage.getHeader().getProtectionAlg().getParameters())); MacCalculator calculator = pkMacBuilder.build(password); OutputStream macOut = calculator.getOutputStream(); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(pkiMessage.getHeader()); v.add(pkiMessage.getBody()); macOut.write(new DERSequence(v).getEncoded(ASN1Encoding.DER)); macOut.close(); return Arrays.areEqual(calculator.getMac(), pkiMessage.getProtection().getBytes()); } catch (Exception e) { throw new CMPException("unable to verify MAC: " + e.getMessage(), e); } }
/** * Creates a new PKMACValue. * @param params parameters for password-based MAC * @param value MAC of the DER-encoded SubjectPublicKeyInfo */ public PKMACValue( PBMParameter params, DERBitString value) { this(new AlgorithmIdentifier( CMPObjectIdentifiers.passwordBasedMac, params), value); }
public static boolean isImplictConfirm(PKIHeader header) { ParamUtil.requireNonNull("header", header); InfoTypeAndValue[] regInfos = header.getGeneralInfo(); if (regInfos == null) { return false; } for (InfoTypeAndValue regInfo : regInfos) { if (CMPObjectIdentifiers.it_implicitConfirm.equals(regInfo.getInfoType())) { return true; } } return false; }
public static CmpUtf8Pairs extract(InfoTypeAndValue[] regInfos) { if (regInfos == null) { return null; } for (InfoTypeAndValue regInfo : regInfos) { if (CMPObjectIdentifiers.regInfo_utf8Pairs.equals(regInfo.getInfoType())) { String regInfoValue = ((ASN1String) regInfo.getInfoValue()).getString(); return new CmpUtf8Pairs(regInfoValue); } } return null; }
public static CmpUtf8Pairs extract(AttributeTypeAndValue[] atvs) { if (atvs == null) { return null; } for (AttributeTypeAndValue atv : atvs) { if (CMPObjectIdentifiers.regInfo_utf8Pairs.equals(atv.getType())) { String regInfoValue = ((ASN1String) atv.getValue()).getString(); return new CmpUtf8Pairs(regInfoValue); } } return null; }
private MacCalculator genCalculator(final PBMParameter params, char[] password) throws CRMFException { // From RFC 4211 // // 1. Generate a random salt value S // // 2. Append the salt to the pw. K = pw || salt. // // 3. Hash the value of K. K = HASH(K) // // 4. Iter = Iter - 1. If Iter is greater than zero. Goto step 3. // // 5. Compute an HMAC as documented in [HMAC]. // // MAC = HASH( K XOR opad, HASH( K XOR ipad, data) ) // // Where opad and ipad are defined in [HMAC]. byte[] pw = Strings.toUTF8ByteArray(password); byte[] salt = params.getSalt().getOctets(); byte[] K = new byte[pw.length + salt.length]; System.arraycopy(pw, 0, K, 0, pw.length); System.arraycopy(salt, 0, K, pw.length, salt.length); calculator.setup(params.getOwf(), params.getMac()); int iter = params.getIterationCount().getValue().intValue(); do { K = calculator.calculateDigest(K); } while (--iter > 0); final byte[] key = K; return new MacCalculator() { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); public AlgorithmIdentifier getAlgorithmIdentifier() { return new AlgorithmIdentifier(CMPObjectIdentifiers.passwordBasedMac, params); } public GenericKey getKey() { return new GenericKey(getAlgorithmIdentifier(), key); } public OutputStream getOutputStream() { return bOut; } public byte[] getMac() { try { return calculator.calculateMac(key, bOut.toByteArray()); } catch (CRMFException e) { throw new RuntimeOperatorException("exception calculating mac: " + e.getMessage(), e); } } }; }
public static InfoTypeAndValue getImplictConfirmGeneralInfo() { return new InfoTypeAndValue(CMPObjectIdentifiers.it_implicitConfirm, DERNull.INSTANCE); }
public static InfoTypeAndValue buildInfoTypeAndValue(CmpUtf8Pairs utf8Pairs) { ParamUtil.requireNonNull("utf8Pairs", utf8Pairs); return new InfoTypeAndValue(CMPObjectIdentifiers.regInfo_utf8Pairs, new DERUTF8String(utf8Pairs.encoded())); }
public static AttributeTypeAndValue buildAttributeTypeAndValue(CmpUtf8Pairs utf8Pairs) { ParamUtil.requireNonNull("utf8Pairs", utf8Pairs); return new AttributeTypeAndValue(CMPObjectIdentifiers.regInfo_utf8Pairs, new DERUTF8String(utf8Pairs.encoded())); }
/** * Determine whether the message is protected by a password based MAC. Use verify(PKMACBuilder, char[]) * to verify the message if this method returns true. * * @return true if protection MAC PBE based, false otherwise. */ public boolean hasPasswordBasedMacProtection() { return pkiMessage.getHeader().getProtectionAlg().getAlgorithm().equals(CMPObjectIdentifiers.passwordBasedMac); }