use of org.xipki.ca.api.profile.x509.KeyUsageControl in project xipki by xipki.
the class XmlX509CertprofileUtil method buildKeyUsageOptions.
// method toOidList
public static Set<KeyUsageControl> buildKeyUsageOptions(org.xipki.ca.certprofile.x509.jaxb.KeyUsage extConf) {
ParamUtil.requireNonNull("extConf", extConf);
List<UsageType> usages = extConf.getUsage();
Set<KeyUsageControl> controls = new HashSet<>();
for (UsageType m : usages) {
boolean required = m.isRequired();
switch(m.getValue()) {
case CRL_SIGN:
controls.add(new KeyUsageControl(KeyUsage.cRLSign, required));
break;
case DATA_ENCIPHERMENT:
controls.add(new KeyUsageControl(KeyUsage.dataEncipherment, required));
break;
case CONTENT_COMMITMENT:
controls.add(new KeyUsageControl(KeyUsage.contentCommitment, required));
break;
case DECIPHER_ONLY:
controls.add(new KeyUsageControl(KeyUsage.decipherOnly, required));
break;
case ENCIPHER_ONLY:
controls.add(new KeyUsageControl(KeyUsage.encipherOnly, required));
break;
case DIGITAL_SIGNATURE:
controls.add(new KeyUsageControl(KeyUsage.digitalSignature, required));
break;
case KEY_AGREEMENT:
controls.add(new KeyUsageControl(KeyUsage.keyAgreement, required));
break;
case KEY_CERT_SIGN:
controls.add(new KeyUsageControl(KeyUsage.keyCertSign, required));
break;
case KEY_ENCIPHERMENT:
controls.add(new KeyUsageControl(KeyUsage.keyEncipherment, required));
break;
default:
throw new RuntimeException("should not reach here, unknown GeneralSubtreeBaseType " + m.getValue());
}
}
return Collections.unmodifiableSet(controls);
}
use of org.xipki.ca.api.profile.x509.KeyUsageControl in project xipki by xipki.
the class ExtensionsChecker method getKeyusage.
// method checkExtensionAuthorizationTemplate
private Set<KeyUsageControl> getKeyusage(boolean required) {
Set<KeyUsageControl> ret = new HashSet<>();
Set<KeyUsageControl> controls = certProfile.getKeyusages();
if (controls != null) {
for (KeyUsageControl control : controls) {
if (control.isRequired() == required) {
ret.add(control);
}
}
}
return ret;
}
use of org.xipki.ca.api.profile.x509.KeyUsageControl in project xipki by xipki.
the class IdentifiedX509Certprofile method getExtensions.
/**
* TODO.
* @param requestedSubject
* Subject requested subject. Must not be {@code null}.
* @param grantedSubject
* Granted subject. Must not be {@code null}.
* @param requestedExtensions
* Extensions requested by the requestor. Could be {@code null}.
* @param publicKeyInfo
* Subject public key. Must not be {@code null}.
* @param publicCaInfo
* CA information. Must not be {@code null}.
* @param crlSignerCert
* CRL signer certificate. Could be {@code null}.
* @param notBefore
* NotBefore. Must not be {@code null}.
* @param notAfter
* NotAfter. Must not be {@code null}.
* @param caInfo
* CA information.
* @return the extensions of the certificate to be issued.
*/
public ExtensionValues getExtensions(X500Name requestedSubject, X500Name grantedSubject, Extensions requestedExtensions, SubjectPublicKeyInfo publicKeyInfo, PublicCaInfo publicCaInfo, X509Certificate crlSignerCert, Date notBefore, Date notAfter) throws CertprofileException, BadCertTemplateException {
ParamUtil.requireNonNull("publicKeyInfo", publicKeyInfo);
ExtensionValues values = new ExtensionValues();
Map<ASN1ObjectIdentifier, ExtensionControl> controls = new HashMap<>(certprofile.getExtensionControls());
Set<ASN1ObjectIdentifier> neededExtTypes = new HashSet<>();
Set<ASN1ObjectIdentifier> wantedExtTypes = new HashSet<>();
if (requestedExtensions != null) {
Extension reqExtension = requestedExtensions.getExtension(ObjectIdentifiers.id_xipki_ext_cmpRequestExtensions);
if (reqExtension != null) {
ExtensionExistence ee = ExtensionExistence.getInstance(reqExtension.getParsedValue());
neededExtTypes.addAll(ee.getNeedExtensions());
wantedExtTypes.addAll(ee.getWantExtensions());
}
for (ASN1ObjectIdentifier oid : neededExtTypes) {
if (wantedExtTypes.contains(oid)) {
wantedExtTypes.remove(oid);
}
if (!controls.containsKey(oid)) {
throw new BadCertTemplateException("could not add needed extension " + oid.getId());
}
}
}
// SubjectKeyIdentifier
ASN1ObjectIdentifier extType = Extension.subjectKeyIdentifier;
ExtensionControl extControl = controls.remove(extType);
if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
byte[] encodedSpki = publicKeyInfo.getPublicKeyData().getBytes();
byte[] skiValue = HashAlgo.SHA1.hash(encodedSpki);
SubjectKeyIdentifier value = new SubjectKeyIdentifier(skiValue);
addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
}
// Authority key identifier
extType = Extension.authorityKeyIdentifier;
extControl = controls.remove(extType);
if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
byte[] ikiValue = publicCaInfo.getSubjectKeyIdentifer();
AuthorityKeyIdentifier value = null;
if (ikiValue != null) {
if (certprofile.includesIssuerAndSerialInAki()) {
GeneralNames x509CaSubject = new GeneralNames(new GeneralName(publicCaInfo.getX500Subject()));
value = new AuthorityKeyIdentifier(ikiValue, x509CaSubject, publicCaInfo.getSerialNumber());
} else {
value = new AuthorityKeyIdentifier(ikiValue);
}
}
addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
}
// IssuerAltName
extType = Extension.issuerAlternativeName;
extControl = controls.remove(extType);
if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
GeneralNames value = publicCaInfo.getSubjectAltName();
addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
}
// AuthorityInfoAccess
extType = Extension.authorityInfoAccess;
extControl = controls.remove(extType);
if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
AuthorityInfoAccessControl aiaControl = certprofile.getAiaControl();
List<String> caIssuers = null;
if (aiaControl == null || aiaControl.isIncludesCaIssuers()) {
caIssuers = publicCaInfo.getCaCertUris();
}
List<String> ocspUris = null;
if (aiaControl == null || aiaControl.isIncludesOcsp()) {
ocspUris = publicCaInfo.getOcspUris();
}
if (CollectionUtil.isNonEmpty(caIssuers) || CollectionUtil.isNonEmpty(ocspUris)) {
AuthorityInformationAccess value = CaUtil.createAuthorityInformationAccess(caIssuers, ocspUris);
addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
}
}
if (controls.containsKey(Extension.cRLDistributionPoints) || controls.containsKey(Extension.freshestCRL)) {
X500Name crlSignerSubject = (crlSignerCert == null) ? null : X500Name.getInstance(crlSignerCert.getSubjectX500Principal().getEncoded());
X500Name x500CaPrincipal = publicCaInfo.getX500Subject();
// CRLDistributionPoints
extType = Extension.cRLDistributionPoints;
extControl = controls.remove(extType);
if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
if (CollectionUtil.isNonEmpty(publicCaInfo.getCrlUris())) {
CRLDistPoint value = CaUtil.createCrlDistributionPoints(publicCaInfo.getCrlUris(), x500CaPrincipal, crlSignerSubject);
addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
}
}
// FreshestCRL
extType = Extension.freshestCRL;
extControl = controls.remove(extType);
if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
if (CollectionUtil.isNonEmpty(publicCaInfo.getDeltaCrlUris())) {
CRLDistPoint value = CaUtil.createCrlDistributionPoints(publicCaInfo.getDeltaCrlUris(), x500CaPrincipal, crlSignerSubject);
addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
}
}
}
// BasicConstraints
extType = Extension.basicConstraints;
extControl = controls.remove(extType);
if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
BasicConstraints value = CaUtil.createBasicConstraints(certprofile.getCertLevel(), certprofile.getPathLenBasicConstraint());
addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
}
// KeyUsage
extType = Extension.keyUsage;
extControl = controls.remove(extType);
if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
Set<KeyUsage> usages = new HashSet<>();
Set<KeyUsageControl> usageOccs = certprofile.getKeyUsage();
for (KeyUsageControl k : usageOccs) {
if (k.isRequired()) {
usages.add(k.getKeyUsage());
}
}
// the optional KeyUsage will only be set if requested explicitly
if (requestedExtensions != null && extControl.isRequest()) {
addRequestedKeyusage(usages, requestedExtensions, usageOccs);
}
org.bouncycastle.asn1.x509.KeyUsage value = X509Util.createKeyUsage(usages);
addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
}
// ExtendedKeyUsage
extType = Extension.extendedKeyUsage;
extControl = controls.remove(extType);
if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
List<ASN1ObjectIdentifier> usages = new LinkedList<>();
Set<ExtKeyUsageControl> usageOccs = certprofile.getExtendedKeyUsages();
for (ExtKeyUsageControl k : usageOccs) {
if (k.isRequired()) {
usages.add(k.getExtKeyUsage());
}
}
// the optional ExtKeyUsage will only be set if requested explicitly
if (requestedExtensions != null && extControl.isRequest()) {
addRequestedExtKeyusage(usages, requestedExtensions, usageOccs);
}
if (extControl.isCritical() && usages.contains(ObjectIdentifiers.id_anyExtendedKeyUsage)) {
extControl = new ExtensionControl(false, extControl.isRequired(), extControl.isRequest());
}
ExtendedKeyUsage value = X509Util.createExtendedUsage(usages);
addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
}
// ocsp-nocheck
extType = ObjectIdentifiers.id_extension_pkix_ocsp_nocheck;
extControl = controls.remove(extType);
if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
// the extension ocsp-nocheck will only be set if requested explicitly
DERNull value = DERNull.INSTANCE;
addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
}
// SubjectInfoAccess
extType = Extension.subjectInfoAccess;
extControl = controls.remove(extType);
if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
ASN1Sequence value = null;
if (requestedExtensions != null && extControl.isRequest()) {
value = createSubjectInfoAccess(requestedExtensions, certprofile.getSubjectInfoAccessModes());
}
addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
}
// remove extensions that are not required frrom the list
List<ASN1ObjectIdentifier> listToRm = null;
for (ASN1ObjectIdentifier extnType : controls.keySet()) {
ExtensionControl ctrl = controls.get(extnType);
if (ctrl.isRequired()) {
continue;
}
if (neededExtTypes.contains(extnType) || wantedExtTypes.contains(extnType)) {
continue;
}
if (listToRm == null) {
listToRm = new LinkedList<>();
}
listToRm.add(extnType);
}
if (listToRm != null) {
for (ASN1ObjectIdentifier extnType : listToRm) {
controls.remove(extnType);
}
}
ExtensionValues subvalues = certprofile.getExtensions(Collections.unmodifiableMap(controls), requestedSubject, grantedSubject, requestedExtensions, notBefore, notAfter, publicCaInfo);
Set<ASN1ObjectIdentifier> extTypes = new HashSet<>(controls.keySet());
for (ASN1ObjectIdentifier type : extTypes) {
extControl = controls.remove(type);
boolean addMe = addMe(type, extControl, neededExtTypes, wantedExtTypes);
if (addMe) {
ExtensionValue value = null;
if (requestedExtensions != null && extControl.isRequest()) {
Extension reqExt = requestedExtensions.getExtension(type);
if (reqExt != null) {
value = new ExtensionValue(reqExt.isCritical(), reqExt.getParsedValue());
}
}
if (value == null) {
value = subvalues.getExtensionValue(type);
}
addExtension(values, type, value, extControl, neededExtTypes, wantedExtTypes);
}
}
Set<ASN1ObjectIdentifier> unprocessedExtTypes = new HashSet<>();
for (ASN1ObjectIdentifier type : controls.keySet()) {
if (controls.get(type).isRequired()) {
unprocessedExtTypes.add(type);
}
}
if (CollectionUtil.isNonEmpty(unprocessedExtTypes)) {
throw new CertprofileException("could not add required extensions " + toString(unprocessedExtTypes));
}
if (CollectionUtil.isNonEmpty(neededExtTypes)) {
throw new BadCertTemplateException("could not add requested extensions " + toString(neededExtTypes));
}
return values;
}
use of org.xipki.ca.api.profile.x509.KeyUsageControl in project xipki by xipki.
the class IdentifiedX509Certprofile method validate.
public void validate() throws CertprofileException {
StringBuilder msg = new StringBuilder();
Map<ASN1ObjectIdentifier, ExtensionControl> controls = getExtensionControls();
// make sure that non-request extensions are not permitted in requests
Set<ASN1ObjectIdentifier> set = new HashSet<>();
for (ASN1ObjectIdentifier type : NONE_REQUEST_EXTENSION_TYPES) {
ExtensionControl control = controls.get(type);
if (control != null && control.isRequest()) {
set.add(type);
}
}
if (CollectionUtil.isNonEmpty(set)) {
msg.append("extensions ").append(toString(set)).append(" must not be contained in request, ");
}
X509CertLevel level = getCertLevel();
boolean ca = (level == X509CertLevel.RootCA) || (level == X509CertLevel.SubCA);
// make sure that CA-only extensions are not permitted in EE certificate
set.clear();
if (!ca) {
set.clear();
for (ASN1ObjectIdentifier type : CA_ONLY_EXTENSION_TYPES) {
if (controls.containsKey(type)) {
set.add(type);
}
}
if (CollectionUtil.isNonEmpty(set)) {
msg.append("EE profile contains CA-only extensions ").append(toString(set)).append(", ");
}
}
// make sure that critical only extensions are not marked as non-critical.
set.clear();
for (ASN1ObjectIdentifier type : controls.keySet()) {
ExtensionControl control = controls.get(type);
if (CRITICAL_ONLY_EXTENSION_TYPES.contains(type)) {
if (!control.isCritical()) {
set.add(type);
}
}
if (ca && CA_CRITICAL_ONLY_EXTENSION_TYPES.contains(type)) {
if (!control.isCritical()) {
set.add(type);
}
}
}
if (CollectionUtil.isNonEmpty(set)) {
msg.append("critical only extensions are marked as non-critical ");
msg.append(toString(set)).append(", ");
}
// make sure that non-critical only extensions are not marked as critical.
set.clear();
for (ASN1ObjectIdentifier type : controls.keySet()) {
ExtensionControl control = controls.get(type);
if (NONCRITICAL_ONLY_EXTENSION_TYPES.contains(type)) {
if (control.isCritical()) {
set.add(type);
}
}
}
if (CollectionUtil.isNonEmpty(set)) {
msg.append("non-critical extensions are marked as critical ").append(toString(set)).append(", ");
}
// make sure that required extensions are present
set.clear();
Set<ASN1ObjectIdentifier> requiredTypes = ca ? REQUIRED_CA_EXTENSION_TYPES : REQUIRED_EE_EXTENSION_TYPES;
for (ASN1ObjectIdentifier type : requiredTypes) {
ExtensionControl extCtrl = controls.get(type);
if (extCtrl == null || !extCtrl.isRequired()) {
set.add(type);
}
}
if (level == X509CertLevel.SubCA) {
ASN1ObjectIdentifier type = Extension.authorityKeyIdentifier;
ExtensionControl extCtrl = controls.get(type);
if (extCtrl == null || !extCtrl.isRequired()) {
set.add(type);
}
}
if (!set.isEmpty()) {
msg.append("required extensions are not marked as required ").append(toString(set)).append(", ");
}
// KeyUsage
Set<KeyUsageControl> usages = getKeyUsage();
if (ca) {
// make sure the CA certificate contains usage keyCertSign
if (!containsKeyusage(usages, KeyUsage.keyCertSign)) {
msg.append("CA profile does not contain keyUsage ").append(KeyUsage.keyCertSign).append(", ");
}
} else {
// make sure the EE certificate does not contain CA-only usages
KeyUsage[] caOnlyUsages = { KeyUsage.keyCertSign, KeyUsage.cRLSign };
Set<KeyUsage> setUsages = new HashSet<>();
for (KeyUsage caOnlyUsage : caOnlyUsages) {
if (containsKeyusage(usages, caOnlyUsage)) {
setUsages.add(caOnlyUsage);
}
}
if (CollectionUtil.isNonEmpty(set)) {
msg.append("EE profile contains CA-only keyUsage ").append(setUsages).append(", ");
}
}
final int len = msg.length();
if (len > 2) {
msg.delete(len - 2, len);
throw new CertprofileException(msg.toString());
}
}
use of org.xipki.ca.api.profile.x509.KeyUsageControl in project xipki by xipki.
the class IdentifiedX509Certprofile method addRequestedKeyusage.
// method addMe
private static void addRequestedKeyusage(Set<KeyUsage> usages, Extensions requestedExtensions, Set<KeyUsageControl> usageOccs) {
Extension extension = requestedExtensions.getExtension(Extension.keyUsage);
if (extension == null) {
return;
}
org.bouncycastle.asn1.x509.KeyUsage reqKeyUsage = org.bouncycastle.asn1.x509.KeyUsage.getInstance(extension.getParsedValue());
for (KeyUsageControl k : usageOccs) {
if (k.isRequired()) {
continue;
}
if (reqKeyUsage.hasUsages(k.getKeyUsage().getBcUsage())) {
usages.add(k.getKeyUsage());
}
}
}
Aggregations