mirror of
https://github.com/nsacyber/HIRS.git
synced 2025-01-31 00:24:00 +00:00
Add SKI to front end. Extract PK from base RIM to validate signature if not found in db
This commit is contained in:
parent
dbfdcdf9fd
commit
e3b5d164a3
@ -5,7 +5,6 @@ import hirs.data.persist.EventLogMeasurements;
|
|||||||
import hirs.data.persist.ReferenceManifest;
|
import hirs.data.persist.ReferenceManifest;
|
||||||
import hirs.data.persist.SupportReferenceManifest;
|
import hirs.data.persist.SupportReferenceManifest;
|
||||||
import hirs.data.persist.SwidResource;
|
import hirs.data.persist.SwidResource;
|
||||||
import hirs.data.persist.certificate.Certificate;
|
|
||||||
import hirs.data.persist.certificate.CertificateAuthorityCredential;
|
import hirs.data.persist.certificate.CertificateAuthorityCredential;
|
||||||
import hirs.persist.CertificateManager;
|
import hirs.persist.CertificateManager;
|
||||||
import hirs.persist.DBManagerException;
|
import hirs.persist.DBManagerException;
|
||||||
@ -26,6 +25,7 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import hirs.tpm.eventlog.TpmPcrEvent;
|
import hirs.tpm.eventlog.TpmPcrEvent;
|
||||||
@ -262,18 +262,21 @@ public class ReferenceManifestDetailsPageController
|
|||||||
|
|
||||||
RIM_VALIDATOR.validateXmlSignature(new ByteArrayInputStream(baseRim.getRimBytes()));
|
RIM_VALIDATOR.validateXmlSignature(new ByteArrayInputStream(baseRim.getRimBytes()));
|
||||||
data.put("signatureValid", RIM_VALIDATOR.isSignatureValid());
|
data.put("signatureValid", RIM_VALIDATOR.isSignatureValid());
|
||||||
if (RIM_VALIDATOR.isSignatureValid()) {
|
data.put("skID", RIM_VALIDATOR.getSubjectKeyIdentifier());
|
||||||
LOGGER.info("Public key: " + RIM_VALIDATOR.getPublicKey().toString());
|
|
||||||
try {
|
try {
|
||||||
Certificate certificate =
|
Set<CertificateAuthorityCredential> certificates =
|
||||||
CertificateAuthorityCredential.select(certificateManager)
|
CertificateAuthorityCredential.select(certificateManager)
|
||||||
.byEncodedPublicKey(RIM_VALIDATOR.getPublicKey().getEncoded())
|
.getCertificates();
|
||||||
.getCertificate();
|
for (CertificateAuthorityCredential cert : certificates) {
|
||||||
data.put("issuerID", certificate.getId().toString());
|
if (Arrays.equals(cert.getEncodedPublicKey(),
|
||||||
} catch (NullPointerException e) {
|
RIM_VALIDATOR.getPublicKey().getEncoded())) {
|
||||||
LOGGER.info("Unable to get signing certificate link: " + e.getMessage());
|
LOGGER.info("Found matching cert!");
|
||||||
|
data.put("issuerID", cert.getId().toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
LOGGER.error("Unable to link signing certificate: " + e.getMessage());
|
||||||
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,15 +335,27 @@
|
|||||||
<c:choose>
|
<c:choose>
|
||||||
<c:when test="${initialData.signatureValid}">
|
<c:when test="${initialData.signatureValid}">
|
||||||
<img src="${passIcon}" title="${signatureValidText}"/>
|
<img src="${passIcon}" title="${signatureValidText}"/>
|
||||||
<c:if test="${not empty initialData.issuerID}">
|
|
||||||
<div><a href="${portal}/certificate-details?id=${initialData.issuerID}&type=certificateauthority">Signing certificate</a></div>
|
|
||||||
</c:if>
|
|
||||||
</c:when>
|
</c:when>
|
||||||
<c:otherwise>
|
<c:otherwise>
|
||||||
<img src="${failIcon}" title="${signatureInvalidText}"/>
|
<img src="${failIcon}" title="${signatureInvalidText}"/>
|
||||||
</c:otherwise>
|
</c:otherwise>
|
||||||
</c:choose>
|
</c:choose>
|
||||||
</span></div>
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>
|
||||||
|
<c:if test="${not empty initialData.issuerID}">
|
||||||
|
<div><a href="${portal}/certificate-details?id=${initialData.issuerID}&type=certificateauthority">Signing certificate</a></div>
|
||||||
|
</c:if>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>
|
||||||
|
<c:if test="${not empty initialData.skID}">
|
||||||
|
<div>Subject Key Identifier: ${initialData.skID}</div>
|
||||||
|
</c:if>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</c:otherwise>
|
</c:otherwise>
|
||||||
|
@ -23,6 +23,7 @@ import javax.xml.crypto.dsig.XMLSignatureException;
|
|||||||
import javax.xml.crypto.dsig.XMLSignatureFactory;
|
import javax.xml.crypto.dsig.XMLSignatureFactory;
|
||||||
import javax.xml.crypto.dsig.dom.DOMValidateContext;
|
import javax.xml.crypto.dsig.dom.DOMValidateContext;
|
||||||
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
|
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
|
||||||
|
import javax.xml.crypto.dsig.keyinfo.KeyValue;
|
||||||
import javax.xml.crypto.dsig.keyinfo.X509Data;
|
import javax.xml.crypto.dsig.keyinfo.X509Data;
|
||||||
import javax.xml.transform.Source;
|
import javax.xml.transform.Source;
|
||||||
import javax.xml.transform.Transformer;
|
import javax.xml.transform.Transformer;
|
||||||
@ -36,6 +37,7 @@ import javax.xml.validation.SchemaFactory;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.security.Key;
|
import java.security.Key;
|
||||||
|
import java.security.KeyException;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
@ -64,6 +66,7 @@ public class ReferenceManifestValidator {
|
|||||||
private Unmarshaller unmarshaller;
|
private Unmarshaller unmarshaller;
|
||||||
private PublicKey publicKey;
|
private PublicKey publicKey;
|
||||||
private Schema schema;
|
private Schema schema;
|
||||||
|
private String subjectKeyIdentifier;
|
||||||
private boolean signatureValid, supportRimValid;
|
private boolean signatureValid, supportRimValid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -93,6 +96,14 @@ public class ReferenceManifestValidator {
|
|||||||
return publicKey;
|
return publicKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for subjectKeyIdentifier.
|
||||||
|
* @return subjectKeyIdentifier
|
||||||
|
*/
|
||||||
|
public String getSubjectKeyIdentifier() {
|
||||||
|
return subjectKeyIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This default constructor creates the Schema object from SCHEMA_URL immediately to save
|
* This default constructor creates the Schema object from SCHEMA_URL immediately to save
|
||||||
* time during validation calls later.
|
* time during validation calls later.
|
||||||
@ -106,6 +117,7 @@ public class ReferenceManifestValidator {
|
|||||||
signatureValid = false;
|
signatureValid = false;
|
||||||
supportRimValid = false;
|
supportRimValid = false;
|
||||||
publicKey = null;
|
publicKey = null;
|
||||||
|
subjectKeyIdentifier = "";
|
||||||
} catch (SAXException e) {
|
} catch (SAXException e) {
|
||||||
LOGGER.warn("Error setting schema for validation!");
|
LOGGER.warn("Error setting schema for validation!");
|
||||||
}
|
}
|
||||||
@ -192,22 +204,21 @@ public class ReferenceManifestValidator {
|
|||||||
if (nodes.getLength() == 0) {
|
if (nodes.getLength() == 0) {
|
||||||
throw new Exception("Signature element not found!");
|
throw new Exception("Signature element not found!");
|
||||||
}
|
}
|
||||||
NodeList embeddedCert = doc.getElementsByTagName("X509Data");
|
|
||||||
if (embeddedCert.getLength() > 0) {
|
|
||||||
X509KeySelector keySelector = new ReferenceManifestValidator.X509KeySelector();
|
X509KeySelector keySelector = new ReferenceManifestValidator.X509KeySelector();
|
||||||
context = new DOMValidateContext(keySelector, nodes.item(0));
|
context = new DOMValidateContext(keySelector, nodes.item(0));
|
||||||
XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance("DOM");
|
XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance("DOM");
|
||||||
XMLSignature signature = sigFactory.unmarshalXMLSignature(context);
|
XMLSignature signature = sigFactory.unmarshalXMLSignature(context);
|
||||||
isValid = signature.validate(context);
|
isValid = signature.validate(context);
|
||||||
publicKey = keySelector.getPublicKey();
|
publicKey = keySelector.getPublicKey();
|
||||||
} else {
|
subjectKeyIdentifier = getKeyName(doc);
|
||||||
LOGGER.info("Signing certificate not found for validation!");
|
} catch (MarshalException e) {
|
||||||
}
|
LOGGER.warn("Error while unmarshalling XML signature: " + e.getMessage());
|
||||||
} catch (MarshalException | XMLSignatureException e) {
|
} catch (XMLSignatureException e) {
|
||||||
LOGGER.warn(e.getMessage());
|
LOGGER.warn("Error while validating XML signature: " + e.getMessage());
|
||||||
|
} catch (KeySelectorException e) {
|
||||||
|
LOGGER.warn("Public key not found in XML signature: " + e.getMessage());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.warn(e.getMessage());
|
LOGGER.warn(e.getMessage());
|
||||||
LOGGER.info(e.getMessage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return isValid;
|
return isValid;
|
||||||
@ -222,7 +233,12 @@ public class ReferenceManifestValidator {
|
|||||||
private PublicKey publicKey;
|
private PublicKey publicKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method selects an X509 cert based on the provided algorithm.
|
* This method selects a public key for validation.
|
||||||
|
* PKs are parsed preferentially from the following elements:
|
||||||
|
* - X509Data
|
||||||
|
* - KeyValue
|
||||||
|
* The parsed PK is then verified based on the provided algorithm before
|
||||||
|
* being returned in a KeySelectorResult.
|
||||||
*
|
*
|
||||||
* @param keyinfo object containing the cert.
|
* @param keyinfo object containing the cert.
|
||||||
* @param purpose purpose.
|
* @param purpose purpose.
|
||||||
@ -246,15 +262,23 @@ public class ReferenceManifestValidator {
|
|||||||
Object object = dataItr.next();
|
Object object = dataItr.next();
|
||||||
if (object instanceof X509Certificate) {
|
if (object instanceof X509Certificate) {
|
||||||
publicKey = ((X509Certificate) object).getPublicKey();
|
publicKey = ((X509Certificate) object).getPublicKey();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (element instanceof KeyValue) {
|
||||||
|
try {
|
||||||
|
publicKey = ((KeyValue) element).getPublicKey();
|
||||||
|
} catch (KeyException e) {
|
||||||
|
LOGGER.warn("KeyException thrown while getting PK from KeyValue: "
|
||||||
|
+ e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (areAlgorithmsEqual(algorithm.getAlgorithm(),
|
if (areAlgorithmsEqual(algorithm.getAlgorithm(),
|
||||||
publicKey.getAlgorithm())) {
|
publicKey.getAlgorithm())) {
|
||||||
return new ReferenceManifestValidator.X509KeySelector
|
return new ReferenceManifestValidator.X509KeySelector
|
||||||
.RIMKeySelectorResult(publicKey);
|
.RIMKeySelectorResult(publicKey);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new KeySelectorException("No key found!");
|
throw new KeySelectorException("No key found!");
|
||||||
}
|
}
|
||||||
@ -295,6 +319,21 @@ public class ReferenceManifestValidator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method parses the subject key identifier from the KeyName element of a signature.
|
||||||
|
*
|
||||||
|
* @param doc
|
||||||
|
* @return SKID if found, or an empty string.
|
||||||
|
*/
|
||||||
|
private String getKeyName(final Document doc) {
|
||||||
|
NodeList keyName = doc.getElementsByTagName("KeyName");
|
||||||
|
if (keyName.getLength() > 0) {
|
||||||
|
return keyName.item(0).getTextContent();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method validates the Document against the schema.
|
* This method validates the Document against the schema.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user