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

feat: add logging while accessing configuration data #93

Merged
merged 4 commits into from
Mar 7, 2024
Merged
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
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,17 +82,27 @@ class ValidatorAndProtector {

public ValidatorAndProtector(NestedEndpointContext nestedEndpoint)
throws GeneralSecurityException, CmpProcessingException {
final VerificationContext inputVerification = nestedEndpoint.getInputVerification();
headerValidator = new MessageHeaderValidator(NESTED_INTERFACE_NAME);
outputProtection = new MsgOutputProtector(nestedEndpoint, NESTED_INTERFACE_NAME);
this.inputVerification = inputVerification;
protectionValidator = new ProtectionValidator(NESTED_INTERFACE_NAME, inputVerification);
this.inputVerification = ConfigLogger.logOptional(
NESTED_INTERFACE_NAME,
"NestedEndpointContext.getInputVerification()",
nestedEndpoint::getInputVerification);
protectionValidator = new ProtectionValidator(
NESTED_INTERFACE_NAME,
ConfigLogger.logOptional(
NESTED_INTERFACE_NAME,
"NestedEndpointContext.getInputVerification()",
nestedEndpoint::getInputVerification));
bodyValidator = new MessageBodyValidator(NESTED_INTERFACE_NAME, (x, y) -> false, null, certProfile);
}

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 +166,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,47 @@
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()));
}
}
Loading
Loading