Skip to content

Commit

Permalink
feat: add logging while accessing configuration data
Browse files Browse the repository at this point in the history
  • Loading branch information
Akretsch committed Feb 28, 2024
1 parent 85f69e9 commit 7914e20
Show file tree
Hide file tree
Showing 38 changed files with 958 additions and 347 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ feat: implement configurable recipient

fix: extension processing in CMP client

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

feat: revocation checking via inventory interface

### 4.1.2 (Feb 28 2024)

feat: add logging while accessing configuration data
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ between CMP RA component, downstream interface, and upstream interface:
which supports dynamic changes.
* Where appropriate, they may depend on a certificate profile
optionally given in CMP request headers.
* If accessing the configuration interface shall be logged, the SLF4J-Logger of
com.siemens.pki.cmpracomponent.util.ConfigLogger must be set to DEBUG, e.g.
start with
-Dorg.slf4j.simpleLogger.log.com.siemens.pki.cmpracomponent.util.ConfigLogger=debug


## Interfaces to inventory for certification request validation
Expand Down
2 changes: 1 addition & 1 deletion 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.1.1</version>
<version>4.1.2</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<parent.basedir>.</parent.basedir>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import com.siemens.pki.cmpracomponent.msgvalidation.MessageHeaderValidator;
import com.siemens.pki.cmpracomponent.msgvalidation.ProtectionValidator;
import com.siemens.pki.cmpracomponent.msgvalidation.ValidatorIF;
import com.siemens.pki.cmpracomponent.util.ConfigLogger;
import com.siemens.pki.cmpracomponent.util.FileTracer;
import com.siemens.pki.cmpracomponent.util.MessageDumper;
import java.security.GeneralSecurityException;
Expand Down Expand Up @@ -81,7 +82,10 @@ class ValidatorAndProtector {

public ValidatorAndProtector(NestedEndpointContext nestedEndpoint)
throws GeneralSecurityException, CmpProcessingException {
final VerificationContext inputVerification = nestedEndpoint.getInputVerification();
final VerificationContext inputVerification = ConfigLogger.logOptional(
NESTED_INTERFACE_NAME,
"NestedEndpointContext.getInputVerification()",
() -> nestedEndpoint.getInputVerification());
headerValidator = new MessageHeaderValidator(NESTED_INTERFACE_NAME);
outputProtection = new MsgOutputProtector(nestedEndpoint, NESTED_INTERFACE_NAME);
this.inputVerification = inputVerification;
Expand All @@ -91,7 +95,10 @@ public ValidatorAndProtector(NestedEndpointContext nestedEndpoint)

private ValidatorAndProtector(String certProfile, final CmpMessageInterface upstreamConfiguration)
throws GeneralSecurityException, CmpProcessingException {
this.inputVerification = upstreamConfiguration.getInputVerification();
this.inputVerification = ConfigLogger.logOptional(
INTERFACE_NAME,
"CmpMessageInterface.getInputVerification()",
() -> upstreamConfiguration.getInputVerification());
headerValidator = new MessageHeaderValidator(INTERFACE_NAME);
outputProtection = new MsgOutputProtector(upstreamConfiguration, INTERFACE_NAME, null);
protectionValidator = new ProtectionValidator(INTERFACE_NAME, inputVerification);
Expand Down Expand Up @@ -155,8 +162,12 @@ private void validateResponse(final PKIMessage response) throws BaseCmpException
this.upstreamExchange = upstreamExchange;
this.certProfile = certProfile;
validatorAndProtector = new ValidatorAndProtector(certProfile, upstreamConfiguration);
nestedValidatorAndProtector =
ifNotNull(upstreamConfiguration.getNestedEndpointContext(), ValidatorAndProtector::new);
nestedValidatorAndProtector = ifNotNull(
ConfigLogger.logOptional(
INTERFACE_NAME,
"CmpMessageInterface.getNestedEndpointContext()",
() -> upstreamConfiguration.getNestedEndpointContext()),
ValidatorAndProtector::new);
}

PKIMessage buildFurtherRequest(final PKIMessage formerResponse, final PKIBody requestBody) throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.siemens.pki.cmpracomponent.configuration.GetCaCertificatesHandler;
import com.siemens.pki.cmpracomponent.configuration.GetCertificateRequestTemplateHandler;
import com.siemens.pki.cmpracomponent.configuration.GetRootCaCertificateUpdateHandler;
import com.siemens.pki.cmpracomponent.configuration.VerificationContext;
import com.siemens.pki.cmpracomponent.cryptoservices.AlgorithmHelper;
import com.siemens.pki.cmpracomponent.cryptoservices.CertUtility;
import com.siemens.pki.cmpracomponent.cryptoservices.CmsDecryptor;
Expand Down Expand Up @@ -131,6 +132,8 @@ public interface EnrollmentResult {

private static final Logger LOGGER = LoggerFactory.getLogger(CmpClient.class);

private static final String INTERFACE_NAME = "cmpclient";

private final ClientRequestHandler requestHandler;

private final ClientContext clientContext;
Expand Down Expand Up @@ -451,14 +454,16 @@ public EnrollmentResult invokeEnrollment() {
case PKIBody.TYPE_CERT_REQ:
case PKIBody.TYPE_INIT_REQ: {
final String subject = enrollmentContext.getSubject();
final Extension[] extensions = ifNotNull(enrollmentContext.getExtensions(), exts -> exts.stream()
.map(ext -> new Extension(
new ASN1ObjectIdentifier(ext.getId()), ext.isCritical(), ext.getValue()))
.toArray(Extension[]::new));
final Extension[] arrayOfExtensions =
ifNotNull(enrollmentContext.getExtensions(), exts -> exts.stream()
.map(ext -> new Extension(
new ASN1ObjectIdentifier(ext.getId()), ext.isCritical(), ext.getValue()))
.toArray(Extension[]::new));
final Extensions extensions = ifNotNull(arrayOfExtensions, Extensions::new);
final CertTemplateBuilder ctb = new CertTemplateBuilder()
.setSubject(ifNotNull(subject, X500Name::new))
.setPublicKey(enrolledPublicKeyInfo)
.setExtensions((Extensions) ifNotNull(extensions, Extensions::new));
.setExtensions(extensions);
requestBody = PkiMessageGenerator.generateIrCrKurBody(
enrollmentType, ctb.build(), null, enrolledPrivateKey);
pvno = enrolledPrivateKey == null ? PKIHeader.CMP_2021 : PKIHeader.CMP_2000;
Expand Down Expand Up @@ -511,7 +516,12 @@ public EnrollmentResult invokeEnrollment() {
LOGGER.error("wrong or missing local credentials, no key decryption possible");
return null;
}
final DataSignVerifier verifier = new DataSignVerifier(requestHandler.getInputVerification());
final VerificationContext inputVerification = requestHandler.getInputVerification();
if (inputVerification == null) {
LOGGER.error("wrong or missing local trust, no key verification possible");
return null;
}
final DataSignVerifier verifier = new DataSignVerifier(inputVerification, INTERFACE_NAME);
final byte[] decryptedKey = decryptor.decrypt(EnvelopedData.getInstance(
certifiedKeyPair.getPrivateKey().getValue()));
enrolledPrivateKey = verifier.verifySignedKey(decryptedKey);
Expand All @@ -533,7 +543,7 @@ public EnrollmentResult invokeEnrollment() {
if (enrollmentContext.getEnrollmentTrust() != null) {
try {
final List<? extends X509Certificate> validationResult = new TrustCredentialAdapter(
enrollmentContext.getEnrollmentTrust())
enrollmentContext.getEnrollmentTrust(), INTERFACE_NAME)
.validateCertAgainstTrust(
enrolledCertAsX509,
CertUtility.asX509Certificates(responseMessage.getExtraCerts()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package com.siemens.pki.cmpracomponent.cryptoservices;

import com.siemens.pki.cmpracomponent.configuration.SignatureCredentialContext;
import com.siemens.pki.cmpracomponent.util.ConfigLogger;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.List;
Expand All @@ -29,40 +30,48 @@
public class BaseCredentialService {

private final SignatureCredentialContext config;
final String interfaceName;

/**
* ctor
* @param config related config
* @param interfaceName CMP interface name for logging
*/
public BaseCredentialService(final SignatureCredentialContext config) {
public BaseCredentialService(final SignatureCredentialContext config, String interfaceName) {
this.config = config;
this.interfaceName = interfaceName;
}

protected List<X509Certificate> getCertChain() {
return config.getCertificateChain();
return ConfigLogger.log(
interfaceName, "SignatureCredentialContext.getCertificateChain()", () -> config.getCertificateChain());
}

/**
* get end certificate
* @return end certificate
*/
public X509Certificate getEndCertificate() {
return config.getCertificateChain().get(0);
return getCertChain().get(0);
}

/**
* get private key related to end certificate
* @return private key related to end certificate
*/
public PrivateKey getPrivateKey() {
return config.getPrivateKey();
return ConfigLogger.log(
interfaceName, "SignatureCredentialContext.getPrivateKey()", () -> config.getPrivateKey());
}

protected AlgorithmIdentifier getSignatureAlgorithm() {
return AlgorithmHelper.getSigningAlgIdFromName(getSignatureAlgorithmName());
}

protected String getSignatureAlgorithmName() {
return config.getSignatureAlgorithmName();
return ConfigLogger.log(
interfaceName,
"SignatureCredentialContext.getSignatureAlgorithmName()",
() -> config.getSignatureAlgorithmName());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,17 @@
package com.siemens.pki.cmpracomponent.cryptoservices;

import com.siemens.pki.cmpracomponent.configuration.CkgContext;
import com.siemens.pki.cmpracomponent.util.ConfigLogger;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import org.bouncycastle.asn1.cms.EnvelopedData;
import org.bouncycastle.asn1.cms.SignedData;
import org.bouncycastle.cms.*;
import org.bouncycastle.cms.CMSAlgorithm;
import org.bouncycastle.cms.CMSEnvelopedData;
import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.RecipientInfoGenerator;
import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;

/**
Expand All @@ -32,9 +38,15 @@ public class CmsEncryptorBase {

private final CMSEnvelopedDataGenerator envGen = new CMSEnvelopedDataGenerator();
private final CkgContext config;
private final String interfaceName;

protected CmsEncryptorBase(final CkgContext config) {
protected CmsEncryptorBase(final CkgContext config, String interfaceName) {
this.config = config;
this.interfaceName = interfaceName;
}

protected void addRecipientInfoGenerator(final RecipientInfoGenerator recipientGenerator) {
envGen.addRecipientInfoGenerator(recipientGenerator);
}

/**
Expand All @@ -49,7 +61,10 @@ protected CmsEncryptorBase(final CkgContext config) {
public EnvelopedData encrypt(final byte[] msg) throws CMSException, NoSuchAlgorithmException {
final CMSEnvelopedData cmsEnvData = envGen.generate(
new CMSProcessableByteArray(msg),
new JceCMSContentEncryptorBuilder(AlgorithmHelper.getKeyEncryptionOID(config.getContentEncryptionAlg()))
new JceCMSContentEncryptorBuilder(AlgorithmHelper.getKeyEncryptionOID(ConfigLogger.log(
interfaceName,
"CkgContext.getContentEncryptionAlg()",
() -> config.getContentEncryptionAlg())))
.setProvider(CertUtility.getBouncyCastleProvider())
.build());
return EnvelopedData.getInstance(cmsEnvData.toASN1Structure().getContent());
Expand All @@ -71,8 +86,4 @@ public EnvelopedData encrypt(final SignedData data) throws CMSException, IOExcep
.build());
return EnvelopedData.getInstance(cmsEnvData.toASN1Structure().getContent());
}

protected void addRecipientInfoGenerator(final RecipientInfoGenerator recipientGenerator) {
envGen.addRecipientInfoGenerator(recipientGenerator);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,10 @@ private static byte[] verifySignature(
/**
* ctor
* @param config context used for verification
* @param interfaceName CMP interface name for logging
*/
public DataSignVerifier(final VerificationContext config) {
super(config);
public DataSignVerifier(final VerificationContext config, String interfaceName) {
super(config, interfaceName);
}

private boolean validate(final X509CertificateHolder cert, final List<X509Certificate> allCerts)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,25 +81,28 @@ public DataSigner(final BaseCredentialService credentialService)
* ctor
* @param privateKey private key used for signing
* @param endCertificate certificate used for signing
* @param interfaceName CMP interface name for logging
* @throws CertificateEncodingException in case of error
* @throws OperatorCreationException in case of error
* @throws IOException in case of error
* @throws CMSException in case of error
*/
public DataSigner(final PrivateKey privateKey, final X509Certificate endCertificate)
public DataSigner(final PrivateKey privateKey, final X509Certificate endCertificate, String interfaceName)
throws CertificateEncodingException, OperatorCreationException, IOException, CMSException {
this(new BaseCredentialService(new SignatureCredentialContext() {
this(new BaseCredentialService(
new SignatureCredentialContext() {

@Override
public List<X509Certificate> getCertificateChain() {
return Collections.singletonList(endCertificate);
}
@Override
public List<X509Certificate> getCertificateChain() {
return Collections.singletonList(endCertificate);
}

@Override
public PrivateKey getPrivateKey() {
return privateKey;
}
}));
@Override
public PrivateKey getPrivateKey() {
return privateKey;
}
},
interfaceName));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.siemens.pki.cmpracomponent.configuration.CkgContext;
import com.siemens.pki.cmpracomponent.configuration.CkgKeyAgreementContext;
import com.siemens.pki.cmpracomponent.msgvalidation.CmpEnrollmentException;
import com.siemens.pki.cmpracomponent.util.ConfigLogger;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
Expand Down Expand Up @@ -49,8 +50,9 @@ public KeyAgreementEncryptor(
final int initialRequestType,
final String interfaceName)
throws GeneralSecurityException, CmpEnrollmentException {
super(config);
final CkgKeyAgreementContext keyAgreementContext = config.getKeyAgreementContext();
super(config, interfaceName);
final CkgKeyAgreementContext keyAgreementContext = ConfigLogger.log(
interfaceName, "CkgContext.getKeyAgreementContext()", () -> config.getKeyAgreementContext());
if (keyAgreementContext == null) {
throw new CmpEnrollmentException(
initialRequestType,
Expand All @@ -59,12 +61,27 @@ public KeyAgreementEncryptor(
"support for key management technique Key Agreement is not configured for central key generation");
}
final JceKeyAgreeRecipientInfoGenerator infGen = new JceKeyAgreeRecipientInfoGenerator(
AlgorithmHelper.getKeyAgreementOID(keyAgreementContext.getKeyAgreementAlg()),
keyAgreementContext.getOwnPrivateKey(),
keyAgreementContext.getOwnPublicKey(),
AlgorithmHelper.getKekOID(keyAgreementContext.getKeyEncryptionAlg()));
AlgorithmHelper.getKeyAgreementOID(ConfigLogger.log(
interfaceName,
"CkgKeyAgreementContext.getKeyAgreementAlg()",
() -> keyAgreementContext.getKeyAgreementAlg())),
ConfigLogger.log(
interfaceName,
"CkgKeyAgreementContext.getOwnPrivateKey()",
() -> keyAgreementContext.getOwnPrivateKey()),
ConfigLogger.log(
interfaceName,
"CkgKeyAgreementContext.getOwnPublicKey()",
() -> keyAgreementContext.getOwnPublicKey()),
AlgorithmHelper.getKekOID(ConfigLogger.log(
interfaceName,
"CkgKeyAgreementContext.getKeyEncryptionAlg()",
() -> keyAgreementContext.getKeyEncryptionAlg())));

infGen.addRecipient(keyAgreementContext.getRecipient(protectingCert));
infGen.addRecipient(ConfigLogger.log(
interfaceName,
"CkgKeyAgreementContext.getRecipient(X509Certificate)",
() -> keyAgreementContext.getRecipient(protectingCert)));
addRecipientInfoGenerator(infGen.setProvider(CertUtility.getBouncyCastleProvider()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.siemens.pki.cmpracomponent.configuration.CkgContext;
import com.siemens.pki.cmpracomponent.configuration.CkgKeyTransportContext;
import com.siemens.pki.cmpracomponent.msgvalidation.CmpEnrollmentException;
import com.siemens.pki.cmpracomponent.util.ConfigLogger;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
Expand Down Expand Up @@ -49,8 +50,9 @@ public KeyTransportEncryptor(
final int initialRequestType,
final String interfaceName)
throws NoSuchAlgorithmException, CmpEnrollmentException {
super(config);
final CkgKeyTransportContext transportContext = config.getKeyTransportContext();
super(config, interfaceName);
final CkgKeyTransportContext transportContext = ConfigLogger.log(
interfaceName, "CkgContext.getKeyTransportContext()", () -> config.getKeyTransportContext());
if (transportContext == null) {
throw new CmpEnrollmentException(
initialRequestType,
Expand All @@ -59,7 +61,10 @@ public KeyTransportEncryptor(
"support for key management technique Key Transport is not configured for central key generation");
}
final JcaX509ExtensionUtils jcaX509ExtensionUtils = new JcaX509ExtensionUtils();
final X509Certificate encryptionCert = transportContext.getRecipient(protectingCert);
final X509Certificate encryptionCert = ConfigLogger.log(
interfaceName,
"CkgKeyTransportContext.getRecipient(X509Certificate)",
() -> transportContext.getRecipient(protectingCert));
final PublicKey publicKey = encryptionCert.getPublicKey();
addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(
jcaX509ExtensionUtils
Expand Down
Loading

0 comments on commit 7914e20

Please sign in to comment.