Skip to content

Commit

Permalink
[Fix Bug 2251981]
Browse files Browse the repository at this point in the history
Default operation flags does not work for some HSM so a new mechanism is
introduced to allow a custom flag list. The certificate generate in the
hsm can be customised in pkispawn config file with `pki_<cert>_opsFlagMask` where `<cert> is one between:

- audit_signing
- sslserver
- subsystem
- ca_signing
- ocsp_signing
- storage
- transport
- ocsp_signing

The value is a comma sepated list of flags (case insensitive) which can
be: encrypt, decrypt, sign, sign_recover, verify, verify_recover, wrap,
unwrap AND derive.
  • Loading branch information
fmarco76 committed Dec 18, 2023
1 parent dc24b51 commit e78e266
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ public class SystemCertData {
@XmlElement
protected String subjectDN;

@XmlElement
protected String opsFlagMask;

@XmlElement
protected String cert;

Expand Down Expand Up @@ -239,6 +242,20 @@ public void setDNSNames(String[] dnsNames) {
this.dnsNames = dnsNames;
}

/**
* @return the certificate operation mask
*/
public String getOpsFlagMask() {
return opsFlagMask;
}

/**
* @param The certificate operation mask. It is a comma separated list of usages including: encrypt, decrypt, sign, sign_recover, verify, verify_recover, wrap, unwrap and derive.
*/
public void setOpsFlagMask(String opsFlagMask) {
this.opsFlagMask = opsFlagMask;
}

@Override
public String toString() {
return "SystemCertData["
Expand Down
8 changes: 8 additions & 0 deletions base/server/etc/default.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ pki_audit_signing_key_size=2048
pki_audit_signing_key_type=rsa
pki_audit_signing_signing_algorithm=SHA256withRSA
pki_audit_signing_token=
pki_audit_signing_opsFlagMask=

pki_backup_keys=False
pki_backup_file=
Expand Down Expand Up @@ -156,6 +157,7 @@ pki_sslserver_key_type=%(pki_ssl_server_key_type)s
pki_sslserver_nickname=%(pki_ssl_server_nickname)s
pki_sslserver_subject_dn=%(pki_ssl_server_subject_dn)s
pki_sslserver_token=%(pki_ssl_server_token)s
pki_sslserver_opsFlagMask=

pki_subsystem_key_algorithm=SHA256withRSA
pki_subsystem_signing_algorithm=SHA256withRSA
Expand All @@ -164,6 +166,7 @@ pki_subsystem_key_type=rsa
pki_subsystem_nickname=subsystemCert cert-%(pki_instance_name)s
pki_subsystem_subject_dn=cn=Subsystem Certificate,ou=%(pki_instance_name)s,o=%(pki_security_domain_name)s
pki_subsystem_token=
pki_subsystem_opsFlagMask=

#Set this if we want to use PSS signing when RSA is specified
pki_use_pss_rsa_signing_algorithm=False
Expand Down Expand Up @@ -353,6 +356,7 @@ pki_ca_signing_serial_number=1
pki_ca_signing_signing_algorithm=SHA256withRSA
pki_ca_signing_subject_dn=cn=CA Signing Certificate,ou=%(pki_instance_name)s,o=%(pki_security_domain_name)s
pki_ca_signing_token=
pki_ca_signing_opsFlagMask=

# DEPRECATED: Use 'pki_ca_signing_csr_path' instead.
pki_external_csr_path=
Expand Down Expand Up @@ -388,6 +392,7 @@ pki_ocsp_signing_nickname=ocspSigningCert cert-%(pki_instance_name)s CA
pki_ocsp_signing_signing_algorithm=SHA256withRSA
pki_ocsp_signing_subject_dn=cn=CA OCSP Signing Certificate,ou=%(pki_instance_name)s,o=%(pki_security_domain_name)s
pki_ocsp_signing_token=
pki_ocsp_signing_opsFlagMask=

pki_profiles_in_ldap=False
pki_random_serial_numbers_enable=False
Expand Down Expand Up @@ -500,6 +505,7 @@ pki_storage_nickname=storageCert cert-%(pki_instance_name)s KRA
pki_storage_signing_algorithm=SHA256withRSA
pki_storage_subject_dn=cn=DRM Storage Certificate,ou=%(pki_instance_name)s,o=%(pki_security_domain_name)s
pki_storage_token=
pki_storage_opsFlagMask=

pki_transport_key_algorithm=SHA256withRSA
pki_transport_key_size=2048
Expand All @@ -508,6 +514,7 @@ pki_transport_nickname=transportCert cert-%(pki_instance_name)s KRA
pki_transport_signing_algorithm=SHA256withRSA
pki_transport_subject_dn=cn=DRM Transport Certificate,ou=%(pki_instance_name)s,o=%(pki_security_domain_name)s
pki_transport_token=
pki_transport_opsFlagMask=

pki_admin_email=%(pki_admin_name)s@%(pki_dns_domainname)s
pki_admin_name=%(pki_admin_uid)s
Expand Down Expand Up @@ -581,6 +588,7 @@ pki_ocsp_signing_nickname=ocspSigningCert cert-%(pki_instance_name)s OCSP
pki_ocsp_signing_signing_algorithm=SHA256withRSA
pki_ocsp_signing_subject_dn=cn=OCSP Signing Certificate,ou=%(pki_instance_name)s,o=%(pki_security_domain_name)s
pki_ocsp_signing_token=
pki_ocsp_signing_opsFlagMask=

pki_admin_email=%(pki_admin_name)s@%(pki_dns_domainname)s
pki_admin_name=%(pki_admin_uid)s
Expand Down
1 change: 1 addition & 0 deletions base/server/python/pki/server/deployment/pkihelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -2890,6 +2890,7 @@ def create_system_cert(self, tag):
cert.nickname = self.mdict["pki_%s_nickname" % tag]
cert.subjectDN = self.mdict["pki_%s_subject_dn" % tag]
cert.token = self.mdict["pki_%s_token" % tag]
cert.opsFlagMask = self.mdict["pki_%s_opsFlagMask" % tag]
return cert

def retrieve_existing_server_cert(self, cfg_file):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ public KeyPair loadKeyPair(X509Certificate cert) throws Exception {
* -TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
* +TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
*/
public KeyPair createECCKeyPair(String tag, CryptoToken token, String curveName, String ecType)
public KeyPair createECCKeyPair(String tag, CryptoToken token, String curveName, String ecType, String usage)
throws Exception {

if (curveName == null) {
Expand All @@ -281,11 +281,17 @@ public KeyPair createECCKeyPair(String tag, CryptoToken token, String curveName,
logger.info("Configurator: - type: " + ecType);

do {
if (tag.equals("sslserver") && ecType.equalsIgnoreCase("ECDH")) {
pair = CryptoUtil.generateECCKeyPair(token, curveName, null, CryptoUtil.ECDH_USAGES_MASK);
if (usage == null || usage.isEmpty()) {
if (tag.equals("sslserver") && ecType.equalsIgnoreCase("ECDH")) {
pair = CryptoUtil.generateECCKeyPair(token, curveName, null, CryptoUtil.ECDH_USAGES_MASK);

} else {
pair = CryptoUtil.generateECCKeyPair(token, curveName, null, CryptoUtil.ECDHE_USAGES_MASK);
}
} else {
pair = CryptoUtil.generateECCKeyPair(token, curveName, null, CryptoUtil.ECDHE_USAGES_MASK);
pair = CryptoUtil.generateECCKeyPair(token, curveName,
CryptoUtil.generateUsage(usage),
CryptoUtil.generateUsage(usage));
}

// XXX - store curve , w
Expand All @@ -303,7 +309,7 @@ public KeyPair createECCKeyPair(String tag, CryptoToken token, String curveName,
return pair;
}

public KeyPair createRSAKeyPair(String tag, CryptoToken token, String keySize)
public KeyPair createRSAKeyPair(String tag, CryptoToken token, String keySize, String usage)
throws Exception {

logger.debug("Configurator.createRSAKeyPair(" + token + ")");
Expand All @@ -317,15 +323,21 @@ public KeyPair createRSAKeyPair(String tag, CryptoToken token, String keySize)
logger.error("Configurator.createRSAKeyPair: tag " + tag);
KeyPair pair = null;
do {
if("transport".equals(tag) || "storage".equals(tag) || "subsystem".equals(tag)) {
pair = CryptoUtil.generateRSAKeyPair(token,size,
CryptoUtil.RSA_KEYPAIR_USAGES,
CryptoUtil.RSA_KEYPAIR_USAGES_MASK);
if (usage == null || usage.isEmpty()) {
if("transport".equals(tag) || "storage".equals(tag) || "subsystem".equals(tag)) {
pair = CryptoUtil.generateRSAKeyPair(token,size,
CryptoUtil.RSA_KEYPAIR_USAGES,
CryptoUtil.RSA_KEYPAIR_USAGES_MASK);
} else {
pair = CryptoUtil.generateRSAKeyPair(token, size);
}
} else {
pair = CryptoUtil.generateRSAKeyPair(token, size);
pair = CryptoUtil.generateRSAKeyPair(token, size,
CryptoUtil.generateUsage(usage),
CryptoUtil.generateUsage(usage));
}

byte id[] = ((org.mozilla.jss.crypto.PrivateKey) pair.getPrivate()).getUniqueID();
byte[] id = ((org.mozilla.jss.crypto.PrivateKey) pair.getPrivate()).getUniqueID();
String kid = CryptoUtil.encodeKeyID(id);

// try to locate the private key
Expand Down Expand Up @@ -605,6 +617,9 @@ public Cert setupCert(CertificateSetupRequest request) throws Exception {
String certType = certData.getType();
logger.info("Configurator: - cert type: " + certType);

String usageMask = certData.getOpsFlagMask();
logger.info("Configurator: - cert usageMask: " + usageMask);

String[] dnsNames = certData.getDNSNames();
if (dnsNames != null) {
logger.info("Configurator: - SAN extension: ");
Expand Down Expand Up @@ -645,10 +660,10 @@ public Cert setupCert(CertificateSetupRequest request) throws Exception {
// Note: IE only supports "ECDHE", but "ECDH" is more efficient.
String ecType = preopConfig.getString("cert." + tag + ".ec.type", "ECDHE");

keyPair = createECCKeyPair(tag, token, keySize, ecType);
keyPair = createECCKeyPair(tag, token, keySize, ecType, usageMask);

} else {
keyPair = createRSAKeyPair(tag, token, keySize);
keyPair = createRSAKeyPair(tag, token, keySize, usageMask);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,18 @@
import org.mozilla.jss.asn1.ANY;
import org.mozilla.jss.asn1.ASN1Value;
import org.mozilla.jss.asn1.BIT_STRING;
import org.mozilla.jss.asn1.INTEGER;
import org.mozilla.jss.asn1.BMPString;
import org.mozilla.jss.asn1.PrintableString;
import org.mozilla.jss.asn1.TeletexString;
import org.mozilla.jss.asn1.UTF8String;
import org.mozilla.jss.asn1.UniversalString;
import org.mozilla.jss.asn1.INTEGER;
import org.mozilla.jss.asn1.InvalidBERException;
import org.mozilla.jss.asn1.NULL;
import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
import org.mozilla.jss.asn1.OCTET_STRING;
import org.mozilla.jss.asn1.PrintableString;
import org.mozilla.jss.asn1.SEQUENCE;
import org.mozilla.jss.asn1.SET;
import org.mozilla.jss.asn1.TeletexString;
import org.mozilla.jss.asn1.UTF8String;
import org.mozilla.jss.asn1.UniversalString;
import org.mozilla.jss.crypto.Algorithm;
import org.mozilla.jss.crypto.Cipher;
import org.mozilla.jss.crypto.CryptoStore;
Expand Down Expand Up @@ -157,8 +157,8 @@
import org.mozilla.jss.pkix.crmf.EncryptedKey;
import org.mozilla.jss.pkix.crmf.EncryptedValue;
import org.mozilla.jss.pkix.crmf.PKIArchiveOptions;
import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
import org.mozilla.jss.pkix.primitive.AVA;
import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
import org.mozilla.jss.pkix.primitive.Name;
import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
import org.mozilla.jss.ssl.SSLCipher;
Expand Down Expand Up @@ -3325,6 +3325,12 @@ public static byte[] getDesParity(byte[] key) throws Exception {

return desKey;
}

public static KeyPairGeneratorSpi.Usage[] generateUsage(String usage) {
return Arrays.stream(usage.toUpperCase().split(",")).map(String::trim)
.map(KeyPairGeneratorSpi.Usage::valueOf).toArray(KeyPairGeneratorSpi.Usage[]::new);

}
}

// START ENABLE_ECC
Expand Down

0 comments on commit e78e266

Please sign in to comment.