Skip to content

Commit

Permalink
Use verification credentials for MAC based protection of outgoing mes…
Browse files Browse the repository at this point in the history
…sages at RaDownstream
  • Loading branch information
kiron-mx committed Apr 30, 2024
1 parent 1ef2dc5 commit 53fe11a
Show file tree
Hide file tree
Showing 11 changed files with 239 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
import com.siemens.pki.cmpracomponent.configuration.CmpMessageInterface.ReprotectMode;
import com.siemens.pki.cmpracomponent.configuration.CredentialContext;
import com.siemens.pki.cmpracomponent.configuration.NestedEndpointContext;
import com.siemens.pki.cmpracomponent.configuration.SharedSecretCredentialContext;
import com.siemens.pki.cmpracomponent.msgvalidation.CmpProcessingException;
import com.siemens.pki.cmpracomponent.msgvalidation.MessageContext;
import com.siemens.pki.cmpracomponent.persistency.PersistencyContext;
import com.siemens.pki.cmpracomponent.protection.ProtectionProvider;
import com.siemens.pki.cmpracomponent.protection.ProtectionProviderFactory;
Expand Down Expand Up @@ -54,11 +56,13 @@ public class MsgOutputProtector {

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

private final CmpMessageInterface.ReprotectMode reprotectMode;
private final ReprotectMode reprotectMode;

private final ProtectionProvider protector;
private final PersistencyContext persistencyContext;

private final CredentialContext protectionCredentials;

private final boolean suppressRedundantExtraCerts;

private final GeneralName recipient;
Expand All @@ -67,26 +71,32 @@ public class MsgOutputProtector {
* ctor
* @param config specific configuration
* @param interfaceName name of interface used in logging messages
* @param persistencyContext reference to transaction specific
* {@link PersistencyContext}
* @param messageContext reference to transaction specific
* {@link MessageContext}
* @throws CmpProcessingException in case of inconsistent configuration
* @throws GeneralSecurityException in case of broken configuration
*/
public MsgOutputProtector(
final CmpMessageInterface config, final String interfaceName, final PersistencyContext persistencyContext)
final CmpMessageInterface config, final String interfaceName, final MessageContext messageContext)
throws CmpProcessingException, GeneralSecurityException {
this.persistencyContext = persistencyContext;
persistencyContext = ifNotNull(messageContext, MessageContext::getPersistencyContext);
suppressRedundantExtraCerts = config.getSuppressRedundantExtraCerts();
reprotectMode = config.getReprotectMode();
recipient = ifNotNull(config.getRecipient(), rec -> new GeneralName(new X500Name(rec)));
final CredentialContext outputCredentials = config.getOutputCredentials();
if (reprotectMode == ReprotectMode.reprotect && outputCredentials == null) {
throw new CmpProcessingException(
interfaceName,
PKIFailureInfo.wrongAuthority,
"reprotectMode is reprotect, but no output credentials are given");
final CredentialContext verificationCredentials = ifNotNull(messageContext, MessageContext::getCredentialContext);
if (verificationCredentials instanceof SharedSecretCredentialContext) {
protectionCredentials = verificationCredentials;
}
else {
protectionCredentials = config.getOutputCredentials();
if (reprotectMode == ReprotectMode.reprotect && protectionCredentials == null) {
throw new CmpProcessingException(
interfaceName,
PKIFailureInfo.wrongAuthority,
"reprotectMode is reprotect, but no output credentials are given");
}
}
protector = ProtectionProviderFactory.createProtectionProvider(outputCredentials);
protector = ProtectionProviderFactory.createProtectionProvider(protectionCredentials);
}

/**
Expand All @@ -102,9 +112,13 @@ public MsgOutputProtector(final NestedEndpointContext config, final String inter
suppressRedundantExtraCerts = false;
reprotectMode = ReprotectMode.reprotect;
recipient = ifNotNull(config.getRecipient(), rec -> new GeneralName(new X500Name(rec)));
protector = ProtectionProviderFactory.createProtectionProvider(config.getOutputCredentials());
protectionCredentials = config.getOutputCredentials();
protector = ProtectionProviderFactory.createProtectionProvider(protectionCredentials);
}

// new MsgoutputProtector with CredentialContext == VerificationContext.credentials


/**
* generate and protect a request
* @param headerProvider the header to use
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@
import com.siemens.pki.cmpracomponent.configuration.NestedEndpointContext;
import com.siemens.pki.cmpracomponent.msggeneration.MsgOutputProtector;
import com.siemens.pki.cmpracomponent.msggeneration.PkiMessageGenerator;
import com.siemens.pki.cmpracomponent.msgvalidation.BaseCmpException;
import com.siemens.pki.cmpracomponent.msgvalidation.CmpProcessingException;
import com.siemens.pki.cmpracomponent.msgvalidation.CmpValidationException;
import com.siemens.pki.cmpracomponent.msgvalidation.InputValidator;
import com.siemens.pki.cmpracomponent.msgvalidation.*;
import com.siemens.pki.cmpracomponent.persistency.PersistencyContext;
import com.siemens.pki.cmpracomponent.persistency.PersistencyContextManager;
import com.siemens.pki.cmpracomponent.util.CmpFuncEx;
Expand Down Expand Up @@ -152,7 +149,7 @@ public PKIMessage handleRequest(final PKIMessage in, final PersistencyContext pe
config.getUpstreamConfiguration(
certProfile, in.getBody().getType()),
INTERFACE_NAME,
pesistencyContext);
new MessageContext(pesistencyContext, null));
sentMessage = outputProtector.protectOutgoingMessage(in, null);
}
final NestedEndpointContext nestedEndpointContext = config.getUpstreamConfiguration(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,7 @@

import static com.siemens.pki.cmpracomponent.util.NullUtil.ifNotNull;

import com.siemens.pki.cmpracomponent.configuration.CheckAndModifyResult;
import com.siemens.pki.cmpracomponent.configuration.CkgContext;
import com.siemens.pki.cmpracomponent.configuration.CmpMessageInterface;
import com.siemens.pki.cmpracomponent.configuration.Configuration;
import com.siemens.pki.cmpracomponent.configuration.InventoryInterface;
import com.siemens.pki.cmpracomponent.configuration.NestedEndpointContext;
import com.siemens.pki.cmpracomponent.configuration.SignatureCredentialContext;
import com.siemens.pki.cmpracomponent.configuration.*;
import com.siemens.pki.cmpracomponent.cryptoservices.CertUtility;
import com.siemens.pki.cmpracomponent.cryptoservices.CmsEncryptorBase;
import com.siemens.pki.cmpracomponent.cryptoservices.DataSigner;
Expand All @@ -36,13 +30,7 @@
import com.siemens.pki.cmpracomponent.cryptoservices.TrustCredentialAdapter;
import com.siemens.pki.cmpracomponent.msggeneration.MsgOutputProtector;
import com.siemens.pki.cmpracomponent.msggeneration.PkiMessageGenerator;
import com.siemens.pki.cmpracomponent.msgvalidation.BaseCmpException;
import com.siemens.pki.cmpracomponent.msgvalidation.CmpEnrollmentException;
import com.siemens.pki.cmpracomponent.msgvalidation.CmpProcessingException;
import com.siemens.pki.cmpracomponent.msgvalidation.CmpValidationException;
import com.siemens.pki.cmpracomponent.msgvalidation.InputValidator;
import com.siemens.pki.cmpracomponent.msgvalidation.MessageHeaderValidator;
import com.siemens.pki.cmpracomponent.msgvalidation.ProtectionValidator;
import com.siemens.pki.cmpracomponent.msgvalidation.*;
import com.siemens.pki.cmpracomponent.persistency.PersistencyContext;
import com.siemens.pki.cmpracomponent.persistency.PersistencyContextManager;
import com.siemens.pki.cmpracomponent.protection.SignatureBasedProtection;
Expand Down Expand Up @@ -121,6 +109,8 @@ class RaDownstream {

private final PersistencyContextManager persistencyContextManager;

private boolean macBasedProtection;

/**
* @param persistencyContextManager persistency interface
* @param config specific configuration
Expand Down Expand Up @@ -174,20 +164,20 @@ protected CmsEncryptorBase buildEncryptor(
return new KeyTransportEncryptor(ckgConfiguration, recipientCert, initialRequestType, interfaceName);
}

private MsgOutputProtector getOutputProtector(final PersistencyContext persistencyContext, final int bodyType)
private MsgOutputProtector getOutputProtector(final MessageContext messageContext, final int bodyType)
throws Exception {
return new MsgOutputProtector(
config.getDownstreamConfiguration(
ifNotNull(persistencyContext, PersistencyContext::getCertProfile), bodyType),
ifNotNull(ifNotNull(messageContext, MessageContext::getPersistencyContext),
PersistencyContext::getCertProfile), bodyType),
INTERFACE_NAME,
persistencyContext);
messageContext);
}

/**
* special handling for CR, IR, KUR
*
* @param incomingCertificateRequest
* @param outputProtector
* @return handled message
* @throws Exception in case of error
*/
Expand Down Expand Up @@ -353,6 +343,7 @@ private PKIMessage handleCrmfCertificateRequest(
*/
PKIMessage handleInputMessage(final PKIMessage in) {
PersistencyContext persistencyContext = null;
MessageContext messageContext = null;
int retryAfterTime = 0;
try {
int responseBodyType = PKIBody.TYPE_ERROR;
Expand All @@ -370,7 +361,7 @@ PKIMessage handleInputMessage(final PKIMessage in) {
headerValidator.validate(in);
final ProtectionValidator protectionValidator = new ProtectionValidator(
NESTED_STRING + INTERFACE_NAME, nestedEndpointContext.getInputVerification());
protectionValidator.validate(in);
CredentialContext credentialContext = protectionValidator.validate(in);
final PKIMessage[] embeddedMessages = PKIMessages.getInstance(
in.getBody().getContent())
.toPKIMessageArray();
Expand All @@ -386,7 +377,7 @@ PKIMessage handleInputMessage(final PKIMessage in) {
final PKIMessage[] responses = Arrays.stream(embeddedMessages)
.map(this::handleInputMessage)
.toArray(PKIMessage[]::new);
return getOutputProtector(persistencyContext, PKIBody.TYPE_NESTED)
return getOutputProtector(new MessageContext(persistencyContext, credentialContext), PKIBody.TYPE_NESTED)
.generateAndProtectResponseTo(
in, new PKIBody(PKIBody.TYPE_NESTED, new PKIMessages(responses)));
}
Expand All @@ -397,11 +388,12 @@ PKIMessage handleInputMessage(final PKIMessage in) {
config::isRaVerifiedAcceptable,
supportedMessageTypes,
persistencyContextManager::loadCreatePersistencyContext);
persistencyContext = inputValidator.validate(in);
final PKIMessage responseFromUpstream = handleValidatedRequest(in, persistencyContext);
messageContext = inputValidator.validate(in);
persistencyContext = messageContext.getPersistencyContext();
final PKIMessage response = handleValidatedRequest(in, messageContext);
// apply downstream protection
final List<CMPCertificate> issuingChain;
responseBodyType = responseFromUpstream.getBody().getType();
responseBodyType = response.getBody().getType();
switch (responseBodyType) {
case PKIBody.TYPE_INIT_REP:
case PKIBody.TYPE_CERT_REP:
Expand All @@ -410,31 +402,31 @@ PKIMessage handleInputMessage(final PKIMessage in) {
break;
case PKIBody.TYPE_POLL_REP:
retryAfterTime = ((PollRepContent)
responseFromUpstream.getBody().getContent())
response.getBody().getContent())
.getCheckAfter(0)
.intPositiveValueExact();
issuingChain = null;
break;
default:
issuingChain = null;
}
return getOutputProtector(persistencyContext, responseBodyType)
return getOutputProtector(messageContext, responseBodyType)
.protectOutgoingMessage(
new PKIMessage(
responseFromUpstream.getHeader(),
responseFromUpstream.getBody(),
responseFromUpstream.getProtection(),
responseFromUpstream.getExtraCerts()),
response.getHeader(),
response.getBody(),
response.getProtection(),
response.getExtraCerts()),
issuingChain);
} catch (final BaseCmpException e) {
final PKIBody errorBody = e.asErrorBody();
responseBodyType = errorBody.getType();
return getOutputProtector(persistencyContext, responseBodyType)
return getOutputProtector(messageContext, responseBodyType)
.generateAndProtectResponseTo(in, errorBody);
} catch (final RuntimeException ex) {
final PKIBody errorBody = new CmpProcessingException(INTERFACE_NAME, ex).asErrorBody();
responseBodyType = errorBody.getType();
return getOutputProtector(persistencyContext, responseBodyType)
return getOutputProtector(messageContext, responseBodyType)
.generateAndProtectResponseTo(in, errorBody);
} finally {
if (persistencyContext != null) {
Expand Down Expand Up @@ -529,10 +521,11 @@ private PKIMessage handleRevocationRequest(PKIMessage incomingRequest, Persisten
}

private PKIMessage handleValidatedRequest(
final PKIMessage incomingRequest, final PersistencyContext persistencyContext) throws Exception {
final PKIMessage incomingRequest, final MessageContext messageContext) throws Exception {
// request pre processing
// by default there is no pre processing
PKIMessage preprocessedRequest = incomingRequest;
final PersistencyContext persistencyContext = messageContext.getPersistencyContext();
switch (incomingRequest.getBody().getType()) {
case PKIBody.TYPE_INIT_REQ:
case PKIBody.TYPE_CERT_REQ:
Expand All @@ -559,7 +552,7 @@ private PKIMessage handleValidatedRequest(
// try to handle locally
persistencyContext.setRequestType(incomingRequest.getBody().getType());
final PKIMessage genmResponse = new ServiceImplementation(config)
.handleValidatedInputMessage(incomingRequest, persistencyContext);
.handleValidatedInputMessage(incomingRequest, messageContext);
if (genmResponse != null) {
return genmResponse;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.siemens.pki.cmpracomponent.msggeneration.MsgOutputProtector;
import com.siemens.pki.cmpracomponent.msgvalidation.BaseCmpException;
import com.siemens.pki.cmpracomponent.msgvalidation.CmpProcessingException;
import com.siemens.pki.cmpracomponent.msgvalidation.MessageContext;
import com.siemens.pki.cmpracomponent.persistency.PersistencyContext;
import java.io.IOException;
import java.security.cert.CRLException;
Expand Down Expand Up @@ -198,14 +199,15 @@ private PKIBody handleGetRootCaCertificateUpdate(
new GenRepContent(new InfoTypeAndValue(CMPObjectIdentifiers.id_it_rootCaKeyUpdate)));
}

protected PKIMessage handleValidatedInputMessage(final PKIMessage msg, final PersistencyContext persistencyContext)
protected PKIMessage handleValidatedInputMessage(final PKIMessage msg, final MessageContext messageContext)
throws BaseCmpException {
try {
final InfoTypeAndValue itav = ((GenMsgContent) msg.getBody().getContent()).toInfoTypeAndValueArray()[0];
final ASN1ObjectIdentifier infoType = itav.getInfoType();

final SupportMessageHandlerInterface messageHandler =
config.getSupportMessageHandler(persistencyContext.getCertProfile(), infoType.getId());
config.getSupportMessageHandler(messageContext.getPersistencyContext().getCertProfile(),
infoType.getId());
if (messageHandler == null) {
return null;
}
Expand All @@ -228,9 +230,10 @@ protected PKIMessage handleValidatedInputMessage(final PKIMessage msg, final Per
}
final MsgOutputProtector protector = new MsgOutputProtector(
config.getDownstreamConfiguration(
ifNotNull(persistencyContext, PersistencyContext::getCertProfile), body.getType()),
ifNotNull(messageContext.getPersistencyContext(), PersistencyContext::getCertProfile),
body.getType()),
INTERFACE_NAME,
persistencyContext);
messageContext);
return protector.generateAndProtectResponseTo(msg, body);
} catch (final BaseCmpException ex) {
throw ex;
Expand Down
Loading

0 comments on commit 53fe11a

Please sign in to comment.