use of org.openecard.bouncycastle.asn1.x509.Extensions 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 org.openecard.bouncycastle.asn1.x509.Extensions in project xipki by xipki.
the class ExtensionsChecker method checkExtensionSubjectAltName.
// method checkExtensionSubjectDirectoryAttributes
private void checkExtensionSubjectAltName(StringBuilder failureMsg, byte[] extensionValue, Extensions requestedExtensions, ExtensionControl extControl, X500Name requestedSubject) {
Set<GeneralNameMode> conf = certProfile.getSubjectAltNameModes();
GeneralName[] requested;
try {
requested = getRequestedSubjectAltNames(requestedSubject, requestedExtensions);
} catch (CertprofileException | BadCertTemplateException ex) {
String msg = "error while derive grantedSubject from requestedSubject";
LogUtil.warn(LOG, ex, msg);
failureMsg.append(msg);
return;
}
if (requested == null) {
failureMsg.append("extension is present but not expected; ");
return;
}
GeneralName[] is = GeneralNames.getInstance(extensionValue).getNames();
GeneralName[] expected = new GeneralName[requested.length];
for (int i = 0; i < is.length; i++) {
try {
expected[i] = createGeneralName(is[i], conf);
} catch (BadCertTemplateException ex) {
failureMsg.append("could not process ").append(i + 1).append("-th name: ").append(ex.getMessage()).append("; ");
return;
}
}
if (is.length != expected.length) {
addViolation(failureMsg, "size of GeneralNames", is.length, expected.length);
return;
}
for (int i = 0; i < is.length; i++) {
if (!is[i].equals(expected[i])) {
failureMsg.append(i + 1).append("-th name does not match the requested one; ");
}
}
}
use of org.openecard.bouncycastle.asn1.x509.Extensions in project xipki by xipki.
the class ExtensionsChecker method checkExtensionKeyUsage.
// method checkExtensionPolicyConstraints
private void checkExtensionKeyUsage(StringBuilder failureMsg, byte[] extensionValue, boolean[] usages, Extensions requestedExtensions, ExtensionControl extControl) {
int len = usages.length;
if (len > 9) {
failureMsg.append("invalid syntax: size of valid bits is larger than 9: ").append(len);
failureMsg.append("; ");
}
Set<String> isUsages = new HashSet<>();
for (int i = 0; i < len; i++) {
if (usages[i]) {
isUsages.add(ALL_USAGES.get(i));
}
}
Set<String> expectedUsages = new HashSet<>();
Set<KeyUsageControl> requiredKeyusage = getKeyusage(true);
for (KeyUsageControl usage : requiredKeyusage) {
expectedUsages.add(usage.getKeyUsage().getName());
}
Set<KeyUsageControl> optionalKeyusage = getKeyusage(false);
if (requestedExtensions != null && extControl.isRequest() && CollectionUtil.isNonEmpty(optionalKeyusage)) {
Extension extension = requestedExtensions.getExtension(Extension.keyUsage);
if (extension != null) {
org.bouncycastle.asn1.x509.KeyUsage reqKeyUsage = org.bouncycastle.asn1.x509.KeyUsage.getInstance(extension.getParsedValue());
for (KeyUsageControl k : optionalKeyusage) {
if (reqKeyUsage.hasUsages(k.getKeyUsage().getBcUsage())) {
expectedUsages.add(k.getKeyUsage().getName());
}
}
}
}
if (CollectionUtil.isEmpty(expectedUsages)) {
byte[] constantExtValue = getConstantExtensionValue(Extension.keyUsage);
if (constantExtValue != null) {
expectedUsages = getKeyUsage(constantExtValue);
}
}
Set<String> diffs = strInBnotInA(expectedUsages, isUsages);
if (CollectionUtil.isNonEmpty(diffs)) {
failureMsg.append("usages ").append(diffs.toString()).append(" are present but not expected; ");
}
diffs = strInBnotInA(isUsages, expectedUsages);
if (CollectionUtil.isNonEmpty(diffs)) {
failureMsg.append("usages ").append(diffs.toString()).append(" are absent but are required; ");
}
}
use of org.openecard.bouncycastle.asn1.x509.Extensions in project xipki by xipki.
the class ExtensionsChecker method checkExtensionInhibitAnyPolicy.
// method checkExtensionPolicyMappings
private void checkExtensionInhibitAnyPolicy(StringBuilder failureMsg, byte[] extensionValue, Extensions requestedExtensions, ExtensionControl extControl) {
QaInhibitAnyPolicy conf = inhibitAnyPolicy;
if (conf == null) {
byte[] expected = getExpectedExtValue(Extension.inhibitAnyPolicy, requestedExtensions, extControl);
if (!Arrays.equals(expected, extensionValue)) {
addViolation(failureMsg, "extension values", extensionValue, (expected == null) ? "not present" : hex(expected));
}
return;
}
ASN1Integer asn1Int = ASN1Integer.getInstance(extensionValue);
int isSkipCerts = asn1Int.getPositiveValue().intValue();
if (isSkipCerts != conf.getSkipCerts()) {
addViolation(failureMsg, "skipCerts", isSkipCerts, conf.getSkipCerts());
}
}
use of org.openecard.bouncycastle.asn1.x509.Extensions in project xipki by xipki.
the class ExtensionsChecker method checkExtensionSubjectDirAttrs.
// method checkExtensionInhibitAnyPolicy
private void checkExtensionSubjectDirAttrs(StringBuilder failureMsg, byte[] extensionValue, Extensions requestedExtensions, ExtensionControl extControl) {
SubjectDirectoryAttributesControl conf = certProfile.getSubjectDirAttrsControl();
if (conf == null) {
failureMsg.append("extension is present but not expected; ");
return;
}
ASN1Encodable extInRequest = null;
if (requestedExtensions != null) {
extInRequest = requestedExtensions.getExtensionParsedValue(Extension.subjectDirectoryAttributes);
}
if (extInRequest == null) {
failureMsg.append("extension is present but not expected; ");
return;
}
SubjectDirectoryAttributes requested = SubjectDirectoryAttributes.getInstance(extInRequest);
Vector<?> reqSubDirAttrs = requested.getAttributes();
ASN1GeneralizedTime expDateOfBirth = null;
String expPlaceOfBirth = null;
String expGender = null;
Set<String> expCountryOfCitizenshipList = new HashSet<>();
Set<String> expCountryOfResidenceList = new HashSet<>();
Map<ASN1ObjectIdentifier, Set<ASN1Encodable>> expOtherAttrs = new HashMap<>();
final int expN = reqSubDirAttrs.size();
for (int i = 0; i < expN; i++) {
Attribute attr = Attribute.getInstance(reqSubDirAttrs.get(i));
ASN1ObjectIdentifier attrType = attr.getAttrType();
ASN1Encodable attrVal = attr.getAttributeValues()[0];
if (ObjectIdentifiers.DN_DATE_OF_BIRTH.equals(attrType)) {
expDateOfBirth = ASN1GeneralizedTime.getInstance(attrVal);
} else if (ObjectIdentifiers.DN_PLACE_OF_BIRTH.equals(attrType)) {
expPlaceOfBirth = DirectoryString.getInstance(attrVal).getString();
} else if (ObjectIdentifiers.DN_GENDER.equals(attrType)) {
expGender = DERPrintableString.getInstance(attrVal).getString();
} else if (ObjectIdentifiers.DN_COUNTRY_OF_CITIZENSHIP.equals(attrType)) {
String country = DERPrintableString.getInstance(attrVal).getString();
expCountryOfCitizenshipList.add(country);
} else if (ObjectIdentifiers.DN_COUNTRY_OF_RESIDENCE.equals(attrType)) {
String country = DERPrintableString.getInstance(attrVal).getString();
expCountryOfResidenceList.add(country);
} else {
Set<ASN1Encodable> otherAttrVals = expOtherAttrs.get(attrType);
if (otherAttrVals == null) {
otherAttrVals = new HashSet<>();
expOtherAttrs.put(attrType, otherAttrVals);
}
otherAttrVals.add(attrVal);
}
}
SubjectDirectoryAttributes ext = SubjectDirectoryAttributes.getInstance(extensionValue);
Vector<?> subDirAttrs = ext.getAttributes();
ASN1GeneralizedTime dateOfBirth = null;
String placeOfBirth = null;
String gender = null;
Set<String> countryOfCitizenshipList = new HashSet<>();
Set<String> countryOfResidenceList = new HashSet<>();
Map<ASN1ObjectIdentifier, Set<ASN1Encodable>> otherAttrs = new HashMap<>();
List<ASN1ObjectIdentifier> attrTypes = new LinkedList<>(conf.getTypes());
final int n = subDirAttrs.size();
for (int i = 0; i < n; i++) {
Attribute attr = Attribute.getInstance(subDirAttrs.get(i));
ASN1ObjectIdentifier attrType = attr.getAttrType();
if (!attrTypes.contains(attrType)) {
failureMsg.append("attribute of type " + attrType.getId()).append(" is present but not expected; ");
continue;
}
ASN1Encodable[] attrs = attr.getAttributeValues();
if (attrs.length != 1) {
failureMsg.append("attribute of type ").append(attrType.getId()).append(" does not single-value value: ").append(attrs.length).append("; ");
continue;
}
ASN1Encodable attrVal = attrs[0];
if (ObjectIdentifiers.DN_DATE_OF_BIRTH.equals(attrType)) {
dateOfBirth = ASN1GeneralizedTime.getInstance(attrVal);
} else if (ObjectIdentifiers.DN_PLACE_OF_BIRTH.equals(attrType)) {
placeOfBirth = DirectoryString.getInstance(attrVal).getString();
} else if (ObjectIdentifiers.DN_GENDER.equals(attrType)) {
gender = DERPrintableString.getInstance(attrVal).getString();
} else if (ObjectIdentifiers.DN_COUNTRY_OF_CITIZENSHIP.equals(attrType)) {
String country = DERPrintableString.getInstance(attrVal).getString();
countryOfCitizenshipList.add(country);
} else if (ObjectIdentifiers.DN_COUNTRY_OF_RESIDENCE.equals(attrType)) {
String country = DERPrintableString.getInstance(attrVal).getString();
countryOfResidenceList.add(country);
} else {
Set<ASN1Encodable> otherAttrVals = otherAttrs.get(attrType);
if (otherAttrVals == null) {
otherAttrVals = new HashSet<>();
otherAttrs.put(attrType, otherAttrVals);
}
otherAttrVals.add(attrVal);
}
}
if (dateOfBirth != null) {
attrTypes.remove(ObjectIdentifiers.DN_DATE_OF_BIRTH);
}
if (placeOfBirth != null) {
attrTypes.remove(ObjectIdentifiers.DN_PLACE_OF_BIRTH);
}
if (gender != null) {
attrTypes.remove(ObjectIdentifiers.DN_GENDER);
}
if (!countryOfCitizenshipList.isEmpty()) {
attrTypes.remove(ObjectIdentifiers.DN_COUNTRY_OF_CITIZENSHIP);
}
if (!countryOfResidenceList.isEmpty()) {
attrTypes.remove(ObjectIdentifiers.DN_COUNTRY_OF_RESIDENCE);
}
attrTypes.removeAll(otherAttrs.keySet());
if (!attrTypes.isEmpty()) {
List<String> attrTypeTexts = new LinkedList<>();
for (ASN1ObjectIdentifier oid : attrTypes) {
attrTypeTexts.add(oid.getId());
}
failureMsg.append("required attributes of types ").append(attrTypeTexts).append(" are not present; ");
}
if (dateOfBirth != null) {
String timeStirng = dateOfBirth.getTimeString();
if (!SubjectDnSpec.PATTERN_DATE_OF_BIRTH.matcher(timeStirng).matches()) {
failureMsg.append("invalid dateOfBirth: " + timeStirng + "; ");
}
String exp = (expDateOfBirth == null) ? null : expDateOfBirth.getTimeString();
if (!timeStirng.equalsIgnoreCase(exp)) {
addViolation(failureMsg, "dateOfBirth", timeStirng, exp);
}
}
if (gender != null) {
if (!(gender.equalsIgnoreCase("F") || gender.equalsIgnoreCase("M"))) {
failureMsg.append("invalid gender: ").append(gender).append("; ");
}
if (!gender.equalsIgnoreCase(expGender)) {
addViolation(failureMsg, "gender", gender, expGender);
}
}
if (placeOfBirth != null) {
if (!placeOfBirth.equals(expPlaceOfBirth)) {
addViolation(failureMsg, "placeOfBirth", placeOfBirth, expPlaceOfBirth);
}
}
if (!countryOfCitizenshipList.isEmpty()) {
Set<String> diffs = strInBnotInA(expCountryOfCitizenshipList, countryOfCitizenshipList);
if (CollectionUtil.isNonEmpty(diffs)) {
failureMsg.append("countryOfCitizenship ").append(diffs.toString()).append(" are present but not expected; ");
}
diffs = strInBnotInA(countryOfCitizenshipList, expCountryOfCitizenshipList);
if (CollectionUtil.isNonEmpty(diffs)) {
failureMsg.append("countryOfCitizenship ").append(diffs.toString()).append(" are absent but are required; ");
}
}
if (!countryOfResidenceList.isEmpty()) {
Set<String> diffs = strInBnotInA(expCountryOfResidenceList, countryOfResidenceList);
if (CollectionUtil.isNonEmpty(diffs)) {
failureMsg.append("countryOfResidence ").append(diffs.toString()).append(" are present but not expected; ");
}
diffs = strInBnotInA(countryOfResidenceList, expCountryOfResidenceList);
if (CollectionUtil.isNonEmpty(diffs)) {
failureMsg.append("countryOfResidence ").append(diffs.toString()).append(" are absent but are required; ");
}
}
if (!otherAttrs.isEmpty()) {
for (ASN1ObjectIdentifier attrType : otherAttrs.keySet()) {
Set<ASN1Encodable> expAttrValues = expOtherAttrs.get(attrType);
if (expAttrValues == null) {
failureMsg.append("attribute of type ").append(attrType.getId()).append(" is present but not requested; ");
continue;
}
Set<ASN1Encodable> attrValues = otherAttrs.get(attrType);
if (!attrValues.equals(expAttrValues)) {
failureMsg.append("attribute of type ").append(attrType.getId()).append(" differs from the requested one; ");
continue;
}
}
}
}
Aggregations