Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enable PQ keys, algorithms and certs for enrollment and protection #123

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ feat: implement configurable recipient

fix: extension processing in CMP client

### 4.1.0 (Dec 14 2023)
### 4.1.0 (Dec 14 2024)

feat: revocation checking via inventory interface

Expand Down
23 changes: 14 additions & 9 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<groupId>com.siemens.pki</groupId>
<artifactId>CmpRaComponent</artifactId>
<packaging>jar</packaging>
<version>4.2.0</version>
<version>4.3.0</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<parent.basedir>.</parent.basedir>
Expand Down Expand Up @@ -93,7 +93,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.10.0</version>
<version>3.10.1</version>
<executions>
<execution>
<id>javadoc-jar</id>
Expand All @@ -118,7 +118,7 @@
<include>src/test/java/**/*.java</include>
</includes>
<palantirJavaFormat>
<version>2.38.0</version>
<version>2.39.0</version>
</palantirJavaFormat>
<importOrder />
<removeUnusedImports />
Expand Down Expand Up @@ -177,7 +177,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.2.5</version>
<version>3.2.7</version>
<executions>
<execution>
<id>sign-artifacts</id>
Expand All @@ -204,7 +204,7 @@
<plugin>
<groupId>org.cyclonedx</groupId>
<artifactId>cyclonedx-maven-plugin</artifactId>
<version>2.8.1</version>
<version>2.8.2</version>
<executions>
<execution>
<phase>package</phase>
Expand All @@ -225,12 +225,17 @@
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<version>1.78.1</version>
<version>1.79</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk18on</artifactId>
<version>1.78.1</version>
<version>1.79</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcutil-jdk18on</artifactId>
<version>1.79</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
Expand All @@ -240,12 +245,12 @@
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.2</version>
<version>2.18.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>2.17.2</version>
<version>2.18.0</version>
</dependency>
<dependency>
<groupId>org.jacoco</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class ValidatorAndProtector {

private final MessageHeaderValidator headerValidator;

private final ValidatorIF<String> bodyValidator;
private final ValidatorIF<Boolean> bodyValidator;

private final VerificationContext inputVerification;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,10 @@
import com.siemens.pki.cmpracomponent.protection.ProtectionProvider;
import com.siemens.pki.cmpracomponent.protection.SignatureBasedProtection;
import com.siemens.pki.cmpracomponent.util.MessageDumper;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
Expand All @@ -63,6 +61,7 @@
import org.bouncycastle.asn1.cmp.CMPObjectIdentifiers;
import org.bouncycastle.asn1.cmp.CRLSource;
import org.bouncycastle.asn1.cmp.CRLStatus;
import org.bouncycastle.asn1.cmp.CertOrEncCert;
import org.bouncycastle.asn1.cmp.CertRepMessage;
import org.bouncycastle.asn1.cmp.CertReqTemplateContent;
import org.bouncycastle.asn1.cmp.CertResponse;
Expand All @@ -76,6 +75,7 @@
import org.bouncycastle.asn1.cmp.PKIStatus;
import org.bouncycastle.asn1.cmp.RevRepContent;
import org.bouncycastle.asn1.cmp.RootCaKeyUpdateContent;
import org.bouncycastle.asn1.cms.ContentInfo;
import org.bouncycastle.asn1.cms.EnvelopedData;
import org.bouncycastle.asn1.crmf.AttributeTypeAndValue;
import org.bouncycastle.asn1.crmf.CertId;
Expand All @@ -89,6 +89,11 @@
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.Time;
import org.bouncycastle.cms.CMSEnvelopedData;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.RecipientInformation;
import org.bouncycastle.cms.RecipientInformationStore;
import org.bouncycastle.cms.jcajce.JceKEMEnvelopedRecipient;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -140,6 +145,7 @@ public interface EnrollmentResult {

/**
* ctor
*
* @param certProfile certificate profile to be used for enrollment.
* <code>null</code> if no certificate profile
* should be used.
Expand Down Expand Up @@ -299,12 +305,11 @@ public List<X509CRL> getCrls(
if (infoValue == null) {
return null;
}
final CertificateFactory certificateFactory = CertUtility.getCertificateFactory();
final ASN1Sequence crls = ASN1Sequence.getInstance(infoValue);
final List<X509CRL> ret = new ArrayList<>(crls.size());
for (final ASN1Encodable aktCrl : crls) {
ret.add((X509CRL) certificateFactory.generateCRL(new ByteArrayInputStream(
aktCrl.toASN1Primitive().getEncoded())));
ret.add(CertUtility.parseCrl(
aktCrl.toASN1Primitive().getEncoded()));
}
return ret;
}
Expand Down Expand Up @@ -497,8 +502,31 @@ public EnrollmentResult invokeEnrollment() {
return null;
}
final CertifiedKeyPair certifiedKeyPair = certResponse.getCertifiedKeyPair();
final CMPCertificate enrolledCertificate =
certifiedKeyPair.getCertOrEncCert().getCertificate();
CertOrEncCert certOrEncCert = certifiedKeyPair.getCertOrEncCert();
CMPCertificate enrolledCertificate = null;
if (certOrEncCert.hasEncryptedCertificate()) {
JceKEMEnvelopedRecipient jkr = new JceKEMEnvelopedRecipient(certificateKeypair.getPrivate());
EnvelopedData envelopedData =
(EnvelopedData) certOrEncCert.getEncryptedCert().getValue();
final CMSEnvelopedData cmsEnvelopedData = new CMSEnvelopedData(
new ContentInfo(envelopedData.getEncryptedContentInfo().getContentType(), envelopedData));
final RecipientInformationStore recipients = cmsEnvelopedData.getRecipientInfos();
for (RecipientInformation recipient : recipients.getRecipients()) {
try {
byte[] content = recipient.getContent(jkr);
enrolledCertificate = CMPCertificate.getInstance(content);
break;
} catch (CMSException ex) {
// try next recipient
}
}
} else {
enrolledCertificate = certOrEncCert.getCertificate();
}
if (enrolledCertificate == null) {
LOGGER.error("could not extract enrolled certificate from response");
return null;
}

if (enrollmentType != PKIBody.TYPE_P10_CERT_REQ && enrolledPrivateKey == null) {
// central key generation in place, decrypt private key
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,17 @@ public interface SignatureCredentialContext extends CredentialContext {
*/
PrivateKey getPrivateKey();

/**
* provide the alternative private key for the end certificate, see X.509 (2019)
* section 9.8
*
* @return private key for first certificate returned by
* {@link #getCertificateChain()}
*/
default PrivateKey getAlternativePrivateKey() {
return null;
}

/**
* provide name or OID of signature algorithm, see <a
* href=https://docs.oracle.com/en/java/javase/11/docs/specs/security/standard-names.html#signature-algorithms>Signature
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Signature;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Mac;
Expand Down Expand Up @@ -245,6 +246,7 @@ String[] extractAliases(final ASN1ObjectIdentifier cmpId) {

/**
* convert shared secrets from byte[] to char[]
*
* @param sharedSecret sharedSecret as byte[]
* @return sharedSecret as char[]
*/
Expand All @@ -261,6 +263,7 @@ public static char[] convertSharedSecretToPassword(final byte[] sharedSecret) {

/**
* get AlgorithmIdentifier for MessageDigest
*
* @param dig digest
* @return AlgorithmIdentifier
*/
Expand Down Expand Up @@ -295,6 +298,7 @@ public static AlgorithmIdentifier getAlgOID(final String algorithm) {

/**
* get OID for name of KEK algorithm
*
* @param id name of KEK algorithm
* @return KEK OID
* @throws NoSuchAlgorithmException if id is unknown
Expand All @@ -305,6 +309,7 @@ public static ASN1ObjectIdentifier getKekOID(final String id) throws NoSuchAlgor

/**
* get OID for key agreement algorithm name
*
* @param id name of key agreement algorithm
* @return key agreement OID
* @throws NoSuchAlgorithmException if id is unknown
Expand All @@ -315,6 +320,7 @@ public static final ASN1ObjectIdentifier getKeyAgreementOID(final String id) thr

/**
* get OID for key encryption algorithm name
*
* @param id name of key encryption algorithm
* @return key encryption OID
* @throws NoSuchAlgorithmException if id is unknown
Expand All @@ -324,7 +330,8 @@ public static ASN1ObjectIdentifier getKeyEncryptionOID(final String id) throws N
}

/**
* get OID for MAC name
* get MAC for name or OID
*
* @param macId name of MAC
* @return mac
* @throws NoSuchAlgorithmException if macId is unknown
Expand All @@ -333,8 +340,20 @@ public static Mac getMac(final String macId) throws NoSuchAlgorithmException {
return Mac.getInstance(macId, CertUtility.getBouncyCastleProvider());
}

/**
* get Signature for name or OID
*
* @param signatureId name of Signature
* @return signature
* @throws NoSuchAlgorithmException if signatureId is unknown
*/
public static Signature getSignature(String signatureId) throws NoSuchAlgorithmException {
return Signature.getInstance(signatureId, CertUtility.getBouncyCastleProvider());
}

/**
* get MessageDigest for MessageDigest name
*
* @param id MessageDigest name
* @return MessageDigest instance
* @throws NoSuchAlgorithmException if nothing found
Expand All @@ -345,6 +364,7 @@ public static MessageDigest getMessageDigest(final String id) throws NoSuchAlgor

/**
* get OID for mac algorithm name
*
* @param macAlg mac algorithm
* @return OID for mac
*/
Expand All @@ -358,6 +378,7 @@ public static ASN1ObjectIdentifier getOidForMac(final String macAlg) {

/**
* get PRF for id of PRF
*
* @param id id of PRF
* @return PRF
* @throws NoSuchAlgorithmException if id is unknown
Expand All @@ -384,6 +405,7 @@ public static SecretKeyFactory getSecretKeyFactory(final String id) throws NoSuc

/**
* get AlgorithmIdentifier of preferred signature algorithm for a key
*
* @param key the key
* @return AlgorithmIdentifier of preferred signature algorithm
*/
Expand All @@ -393,14 +415,17 @@ public static AlgorithmIdentifier getSigningAlgIdFromKey(final Key key) {

/**
* get AlgorithmIdentifier for keyAlgorithm name
*
* @param keyAlgorithm name
* @return AlgorithmIdentifier
*/
public static AlgorithmIdentifier getSigningAlgIdFromKeyAlg(final String keyAlgorithm) {
return DEFAULT_SIGNATURE_ALGORITHM_IDENTIFIER_FINDER.find(getSigningAlgNameFromKeyAlg(keyAlgorithm));
}

/**
* get AlgorithmIdentifier for signatureAlgorithmName
*
* @param signatureAlgorithmName the name
* @return AlgorithmIdentifier
*/
Expand All @@ -427,15 +452,15 @@ public static String getSigningAlgNameFromKey(final Key key) {
* key uses algorithms beside RSA, EC or EdDSA
*/
public static String getSigningAlgNameFromKeyAlg(final String keyAlgorithm) {
if (keyAlgorithm.startsWith("Ed")) {
// EdDSA key
return keyAlgorithm;
}
if ("EC".equals(keyAlgorithm)) {
if (keyAlgorithm.startsWith("EC")) {
// EC key
return "SHA256withECDSA";
}
return "SHA256with" + keyAlgorithm;
if (keyAlgorithm.startsWith("RSA")) {
return "SHA256with" + keyAlgorithm;
}

return keyAlgorithm;
}

/**
Expand All @@ -454,6 +479,7 @@ public enum PasswordBasedMacAlg {

/**
* get an Password-based message authentication code (MAC) algorithms
*
* @param passwordBasedMacAlgorithm id of Password-Based MAC used for protection
* @return related {@link PasswordBasedMacAlg}
* @throws NoSuchAlgorithmException if id is unknown
Expand Down
Loading
Loading