use of com.github.zhenwei.pkix.util.asn1.crmf.ProofOfPossession in project LinLong-Java by zhenwei1108.
the class CertificateRequestMessage method isValidSigningKeyPOP.
/**
* Return whether or not a signing key proof-of-possession (POP), with an associated PKMAC, is
* valid.
*
* @param verifierProvider a provider that can produce content verifiers for the signature
* contained in this POP.
* @param macBuilder a suitable PKMACBuilder to create the MAC verifier.
* @param password the password used to key the MAC calculation.
* @return true if the POP is valid, false otherwise.
* @throws CRMFException if there is a problem in verification or content verifier
* creation.
* @throws IllegalStateException if POP not appropriate.
*/
public boolean isValidSigningKeyPOP(ContentVerifierProvider verifierProvider, PKMACBuilder macBuilder, char[] password) throws CRMFException, IllegalStateException {
ProofOfPossession pop = certReqMsg.getPopo();
if (pop.getType() == popSigningKey) {
POPOSigningKey popoSign = POPOSigningKey.getInstance(pop.getObject());
if (popoSign.getPoposkInput() == null || popoSign.getPoposkInput().getSender() != null) {
throw new IllegalStateException("no PKMAC present in proof of possession");
}
PKMACValue pkMAC = popoSign.getPoposkInput().getPublicKeyMAC();
PKMACValueVerifier macVerifier = new PKMACValueVerifier(macBuilder);
if (macVerifier.isValid(pkMAC, password, this.getCertTemplate().getPublicKey())) {
return verifySignature(verifierProvider, popoSign);
}
return false;
} else {
throw new IllegalStateException("not Signing Key type of proof of possession");
}
}
use of com.github.zhenwei.pkix.util.asn1.crmf.ProofOfPossession in project xipki by xipki.
the class X509CaCmpResponderImpl method verifyPopo.
// method revokePendingCertificates
private boolean verifyPopo(CertificateRequestMessage certRequest, boolean allowRaPopo) {
int popType = certRequest.getProofOfPossessionType();
if (popType == CertificateRequestMessage.popRaVerified && allowRaPopo) {
return true;
}
if (popType != CertificateRequestMessage.popSigningKey) {
LOG.error("unsupported POP type: " + popType);
return false;
}
// check the POP signature algorithm
ProofOfPossession pop = certRequest.toASN1Structure().getPopo();
POPOSigningKey popoSign = POPOSigningKey.getInstance(pop.getObject());
AlgorithmIdentifier popoAlgId = popoSign.getAlgorithmIdentifier();
AlgorithmValidator algoValidator = getCmpControl().getPopoAlgoValidator();
if (!algoValidator.isAlgorithmPermitted(popoAlgId)) {
String algoName;
try {
algoName = AlgorithmUtil.getSignatureAlgoName(popoAlgId);
} catch (NoSuchAlgorithmException ex) {
algoName = popoAlgId.getAlgorithm().getId();
}
LOG.error("POPO signature algorithm {} not permitted", algoName);
return false;
}
try {
PublicKey publicKey = securityFactory.generatePublicKey(certRequest.getCertTemplate().getPublicKey());
ContentVerifierProvider cvp = securityFactory.getContentVerifierProvider(publicKey);
return certRequest.isValidSigningKeyPOP(cvp);
} catch (InvalidKeyException | IllegalStateException | CRMFException ex) {
LogUtil.error(LOG, ex);
}
return false;
}
use of com.github.zhenwei.pkix.util.asn1.crmf.ProofOfPossession in project xipki by xipki.
the class CmpCaClient method requestCertViaCrmf.
public X509Certificate requestCertViaCrmf(String certProfile, PrivateKey privateKey, SubjectPublicKeyInfo publicKeyInfo, String subject) throws Exception {
CertTemplateBuilder certTemplateBuilder = new CertTemplateBuilder();
certTemplateBuilder.setSubject(new X500Name(subject));
certTemplateBuilder.setPublicKey(publicKeyInfo);
CertRequest certReq = new CertRequest(1, certTemplateBuilder.build(), null);
ProofOfPossessionSigningKeyBuilder popoBuilder = new ProofOfPossessionSigningKeyBuilder(certReq);
ContentSigner popoSigner = buildSigner(privateKey);
POPOSigningKey popoSk = popoBuilder.build(popoSigner);
ProofOfPossession popo = new ProofOfPossession(popoSk);
AttributeTypeAndValue certprofileInfo = new AttributeTypeAndValue(CMPObjectIdentifiers.regInfo_utf8Pairs, new DERUTF8String("CERT-PROFILE?" + certProfile + "%"));
AttributeTypeAndValue[] atvs = { certprofileInfo };
CertReqMsg certReqMsg = new CertReqMsg(certReq, popo, atvs);
PKIBody body = new PKIBody(PKIBody.TYPE_CERT_REQ, new CertReqMessages(certReqMsg));
ProtectedPKIMessageBuilder builder = new ProtectedPKIMessageBuilder(PKIHeader.CMP_2000, requestorSubject, responderSubject);
builder.setMessageTime(new Date());
builder.setTransactionID(randomTransactionId());
builder.setSenderNonce(randomSenderNonce());
builder.addGeneralInfo(new InfoTypeAndValue(CMPObjectIdentifiers.it_implicitConfirm, DERNull.INSTANCE));
builder.setBody(body);
ProtectedPKIMessage request = builder.build(requestorSigner);
PKIMessage response = transmit(request);
return parseEnrollCertResult(response);
}
use of com.github.zhenwei.pkix.util.asn1.crmf.ProofOfPossession in project xipki by xipki.
the class EnrollCertAction method execute0.
@Override
protected Object execute0() throws Exception {
if (caName != null) {
caName = caName.toLowerCase();
}
CertTemplateBuilder certTemplateBuilder = new CertTemplateBuilder();
ConcurrentContentSigner signer = getSigner(new SignatureAlgoControl(rsaMgf1, dsaPlain, gm));
X509CertificateHolder ssCert = signer.getBcCertificate();
X500Name x500Subject = new X500Name(subject);
certTemplateBuilder.setSubject(x500Subject);
certTemplateBuilder.setPublicKey(ssCert.getSubjectPublicKeyInfo());
if (StringUtil.isNotBlank(notBeforeS) || StringUtil.isNotBlank(notAfterS)) {
Time notBefore = StringUtil.isNotBlank(notBeforeS) ? new Time(DateUtil.parseUtcTimeyyyyMMddhhmmss(notBeforeS)) : null;
Time notAfter = StringUtil.isNotBlank(notAfterS) ? new Time(DateUtil.parseUtcTimeyyyyMMddhhmmss(notAfterS)) : null;
OptionalValidity validity = new OptionalValidity(notBefore, notAfter);
certTemplateBuilder.setValidity(validity);
}
if (needExtensionTypes == null) {
needExtensionTypes = new LinkedList<>();
}
// SubjectAltNames
List<Extension> extensions = new LinkedList<>();
if (isNotEmpty(subjectAltNames)) {
extensions.add(X509Util.createExtnSubjectAltName(subjectAltNames, false));
needExtensionTypes.add(Extension.subjectAlternativeName.getId());
}
// SubjectInfoAccess
if (isNotEmpty(subjectInfoAccesses)) {
extensions.add(X509Util.createExtnSubjectInfoAccess(subjectInfoAccesses, false));
needExtensionTypes.add(Extension.subjectInfoAccess.getId());
}
// Keyusage
if (isNotEmpty(keyusages)) {
Set<KeyUsage> usages = new HashSet<>();
for (String usage : keyusages) {
usages.add(KeyUsage.getKeyUsage(usage));
}
org.bouncycastle.asn1.x509.KeyUsage extValue = X509Util.createKeyUsage(usages);
ASN1ObjectIdentifier extType = Extension.keyUsage;
extensions.add(new Extension(extType, false, extValue.getEncoded()));
needExtensionTypes.add(extType.getId());
}
// ExtendedKeyusage
if (isNotEmpty(extkeyusages)) {
ExtendedKeyUsage extValue = X509Util.createExtendedUsage(textToAsn1ObjectIdentifers(extkeyusages));
ASN1ObjectIdentifier extType = Extension.extendedKeyUsage;
extensions.add(new Extension(extType, false, extValue.getEncoded()));
needExtensionTypes.add(extType.getId());
}
// QcEuLimitValue
if (isNotEmpty(qcEuLimits)) {
ASN1EncodableVector vec = new ASN1EncodableVector();
for (String m : qcEuLimits) {
StringTokenizer st = new StringTokenizer(m, ":");
try {
String currencyS = st.nextToken();
String amountS = st.nextToken();
String exponentS = st.nextToken();
Iso4217CurrencyCode currency;
try {
int intValue = Integer.parseInt(currencyS);
currency = new Iso4217CurrencyCode(intValue);
} catch (NumberFormatException ex) {
currency = new Iso4217CurrencyCode(currencyS);
}
int amount = Integer.parseInt(amountS);
int exponent = Integer.parseInt(exponentS);
MonetaryValue monterayValue = new MonetaryValue(currency, amount, exponent);
QCStatement statment = new QCStatement(ObjectIdentifiers.id_etsi_qcs_QcLimitValue, monterayValue);
vec.add(statment);
} catch (Exception ex) {
throw new Exception("invalid qc-eu-limit '" + m + "'");
}
}
ASN1ObjectIdentifier extType = Extension.qCStatements;
ASN1Sequence extValue = new DERSequence(vec);
extensions.add(new Extension(extType, false, extValue.getEncoded()));
needExtensionTypes.add(extType.getId());
}
// biometricInfo
if (biometricType != null && biometricHashAlgo != null && biometricFile != null) {
TypeOfBiometricData objBiometricType = StringUtil.isNumber(biometricType) ? new TypeOfBiometricData(Integer.parseInt(biometricType)) : new TypeOfBiometricData(new ASN1ObjectIdentifier(biometricType));
ASN1ObjectIdentifier objBiometricHashAlgo = AlgorithmUtil.getHashAlg(biometricHashAlgo);
byte[] biometricBytes = IoUtil.read(biometricFile);
MessageDigest md = MessageDigest.getInstance(objBiometricHashAlgo.getId());
md.reset();
byte[] biometricDataHash = md.digest(biometricBytes);
DERIA5String sourceDataUri = null;
if (biometricUri != null) {
sourceDataUri = new DERIA5String(biometricUri);
}
BiometricData biometricData = new BiometricData(objBiometricType, new AlgorithmIdentifier(objBiometricHashAlgo), new DEROctetString(biometricDataHash), sourceDataUri);
ASN1EncodableVector vec = new ASN1EncodableVector();
vec.add(biometricData);
ASN1ObjectIdentifier extType = Extension.biometricInfo;
ASN1Sequence extValue = new DERSequence(vec);
extensions.add(new Extension(extType, false, extValue.getEncoded()));
needExtensionTypes.add(extType.getId());
} else if (biometricType == null && biometricHashAlgo == null && biometricFile == null) {
// Do nothing
} else {
throw new Exception("either all of biometric triples (type, hash algo, file)" + " must be set or none of them should be set");
}
if (isNotEmpty(needExtensionTypes) || isNotEmpty(wantExtensionTypes)) {
ExtensionExistence ee = new ExtensionExistence(textToAsn1ObjectIdentifers(needExtensionTypes), textToAsn1ObjectIdentifers(wantExtensionTypes));
extensions.add(new Extension(ObjectIdentifiers.id_xipki_ext_cmpRequestExtensions, false, ee.toASN1Primitive().getEncoded()));
}
if (isNotEmpty(extensions)) {
Extensions asn1Extensions = new Extensions(extensions.toArray(new Extension[0]));
certTemplateBuilder.setExtensions(asn1Extensions);
}
CertRequest certReq = new CertRequest(1, certTemplateBuilder.build(), null);
ProofOfPossessionSigningKeyBuilder popoBuilder = new ProofOfPossessionSigningKeyBuilder(certReq);
ConcurrentBagEntrySigner signer0 = signer.borrowSigner();
POPOSigningKey popoSk;
try {
popoSk = popoBuilder.build(signer0.value());
} finally {
signer.requiteSigner(signer0);
}
ProofOfPossession popo = new ProofOfPossession(popoSk);
EnrollCertRequestEntry reqEntry = new EnrollCertRequestEntry("id-1", profile, certReq, popo);
EnrollCertRequest request = new EnrollCertRequest(EnrollCertRequest.Type.CERT_REQ);
request.addRequestEntry(reqEntry);
RequestResponseDebug debug = getRequestResponseDebug();
EnrollCertResult result;
try {
result = caClient.requestCerts(caName, request, debug);
} finally {
saveRequestResponse(debug);
}
X509Certificate cert = null;
if (result != null) {
String id = result.getAllIds().iterator().next();
CertOrError certOrError = result.getCertOrError(id);
cert = (X509Certificate) certOrError.getCertificate();
}
if (cert == null) {
throw new CmdFailure("no certificate received from the server");
}
File certFile = new File(outputFile);
saveVerbose("saved certificate to file", certFile, cert.getEncoded());
return null;
}
use of com.github.zhenwei.pkix.util.asn1.crmf.ProofOfPossession in project xipki by xipki.
the class BaseCmpResponder method verifyPopo.
protected boolean verifyPopo(CertificateRequestMessage certRequest, SubjectPublicKeyInfo spki, boolean allowRaPopo) {
int popType = certRequest.getProofOfPossessionType();
if (popType == CertificateRequestMessage.popRaVerified && allowRaPopo) {
return true;
}
if (popType != CertificateRequestMessage.popSigningKey) {
LOG.error("unsupported POP type: " + popType);
return false;
}
// check the POP signature algorithm
ProofOfPossession pop = certRequest.toASN1Structure().getPopo();
POPOSigningKey popoSign = POPOSigningKey.getInstance(pop.getObject());
SignAlgo popoAlg;
try {
popoAlg = SignAlgo.getInstance(popoSign.getAlgorithmIdentifier());
} catch (NoSuchAlgorithmException ex) {
LogUtil.error(LOG, ex, "Cannot parse POPO signature algorithm");
return false;
}
AlgorithmValidator algoValidator = getCmpControl().getPopoAlgoValidator();
if (!algoValidator.isAlgorithmPermitted(popoAlg)) {
LOG.error("POPO signature algorithm {} not permitted", popoAlg.getJceName());
return false;
}
try {
PublicKey publicKey = securityFactory.generatePublicKey(spki);
DhpocControl dhpocControl = getCa().getCaInfo().getDhpocControl();
DHSigStaticKeyCertPair kaKeyAndCert = null;
if (SignAlgo.DHPOP_X25519 == popoAlg || SignAlgo.DHPOP_X448 == popoAlg) {
if (dhpocControl != null) {
DhSigStatic dhSigStatic = DhSigStatic.getInstance(popoSign.getSignature().getBytes());
IssuerAndSerialNumber isn = dhSigStatic.getIssuerAndSerial();
ASN1ObjectIdentifier keyAlgOid = spki.getAlgorithm().getAlgorithm();
kaKeyAndCert = dhpocControl.getKeyCertPair(isn.getName(), isn.getSerialNumber().getValue(), EdECConstants.getName(keyAlgOid));
}
if (kaKeyAndCert == null) {
return false;
}
}
ContentVerifierProvider cvp = securityFactory.getContentVerifierProvider(publicKey, kaKeyAndCert);
return certRequest.isValidSigningKeyPOP(cvp);
} catch (InvalidKeyException | IllegalStateException | CRMFException ex) {
LogUtil.error(LOG, ex);
}
return false;
}
Aggregations