mirror of
https://github.com/nsacyber/HIRS.git
synced 2025-01-18 10:46:39 +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.SupportReferenceManifest;
|
||||
import hirs.data.persist.SwidResource;
|
||||
import hirs.data.persist.certificate.Certificate;
|
||||
import hirs.data.persist.certificate.CertificateAuthorityCredential;
|
||||
import hirs.persist.CertificateManager;
|
||||
import hirs.persist.DBManagerException;
|
||||
@ -26,6 +25,7 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import hirs.tpm.eventlog.TpmPcrEvent;
|
||||
@ -262,17 +262,20 @@ public class ReferenceManifestDetailsPageController
|
||||
|
||||
RIM_VALIDATOR.validateXmlSignature(new ByteArrayInputStream(baseRim.getRimBytes()));
|
||||
data.put("signatureValid", RIM_VALIDATOR.isSignatureValid());
|
||||
if (RIM_VALIDATOR.isSignatureValid()) {
|
||||
LOGGER.info("Public key: " + RIM_VALIDATOR.getPublicKey().toString());
|
||||
try {
|
||||
Certificate certificate =
|
||||
CertificateAuthorityCredential.select(certificateManager)
|
||||
.byEncodedPublicKey(RIM_VALIDATOR.getPublicKey().getEncoded())
|
||||
.getCertificate();
|
||||
data.put("issuerID", certificate.getId().toString());
|
||||
} catch (NullPointerException e) {
|
||||
LOGGER.info("Unable to get signing certificate link: " + e.getMessage());
|
||||
data.put("skID", RIM_VALIDATOR.getSubjectKeyIdentifier());
|
||||
try {
|
||||
Set<CertificateAuthorityCredential> certificates =
|
||||
CertificateAuthorityCredential.select(certificateManager)
|
||||
.getCertificates();
|
||||
for (CertificateAuthorityCredential cert : certificates) {
|
||||
if (Arrays.equals(cert.getEncodedPublicKey(),
|
||||
RIM_VALIDATOR.getPublicKey().getEncoded())) {
|
||||
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;
|
||||
}
|
||||
|
@ -335,15 +335,27 @@
|
||||
<c:choose>
|
||||
<c:when test="${initialData.signatureValid}">
|
||||
<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:otherwise>
|
||||
<img src="${failIcon}" title="${signatureInvalidText}"/>
|
||||
</c:otherwise>
|
||||
</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>
|
||||
</c:otherwise>
|
||||
|
@ -23,6 +23,7 @@ import javax.xml.crypto.dsig.XMLSignatureException;
|
||||
import javax.xml.crypto.dsig.XMLSignatureFactory;
|
||||
import javax.xml.crypto.dsig.dom.DOMValidateContext;
|
||||
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
|
||||
import javax.xml.crypto.dsig.keyinfo.KeyValue;
|
||||
import javax.xml.crypto.dsig.keyinfo.X509Data;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.Transformer;
|
||||
@ -36,6 +37,7 @@ import javax.xml.validation.SchemaFactory;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.Key;
|
||||
import java.security.KeyException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
@ -64,6 +66,7 @@ public class ReferenceManifestValidator {
|
||||
private Unmarshaller unmarshaller;
|
||||
private PublicKey publicKey;
|
||||
private Schema schema;
|
||||
private String subjectKeyIdentifier;
|
||||
private boolean signatureValid, supportRimValid;
|
||||
|
||||
/**
|
||||
@ -93,6 +96,14 @@ public class ReferenceManifestValidator {
|
||||
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
|
||||
* time during validation calls later.
|
||||
@ -106,6 +117,7 @@ public class ReferenceManifestValidator {
|
||||
signatureValid = false;
|
||||
supportRimValid = false;
|
||||
publicKey = null;
|
||||
subjectKeyIdentifier = "";
|
||||
} catch (SAXException e) {
|
||||
LOGGER.warn("Error setting schema for validation!");
|
||||
}
|
||||
@ -192,22 +204,21 @@ public class ReferenceManifestValidator {
|
||||
if (nodes.getLength() == 0) {
|
||||
throw new Exception("Signature element not found!");
|
||||
}
|
||||
NodeList embeddedCert = doc.getElementsByTagName("X509Data");
|
||||
if (embeddedCert.getLength() > 0) {
|
||||
X509KeySelector keySelector = new ReferenceManifestValidator.X509KeySelector();
|
||||
context = new DOMValidateContext(keySelector, nodes.item(0));
|
||||
XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance("DOM");
|
||||
XMLSignature signature = sigFactory.unmarshalXMLSignature(context);
|
||||
isValid = signature.validate(context);
|
||||
publicKey = keySelector.getPublicKey();
|
||||
} else {
|
||||
LOGGER.info("Signing certificate not found for validation!");
|
||||
}
|
||||
} catch (MarshalException | XMLSignatureException e) {
|
||||
LOGGER.warn(e.getMessage());
|
||||
X509KeySelector keySelector = new ReferenceManifestValidator.X509KeySelector();
|
||||
context = new DOMValidateContext(keySelector, nodes.item(0));
|
||||
XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance("DOM");
|
||||
XMLSignature signature = sigFactory.unmarshalXMLSignature(context);
|
||||
isValid = signature.validate(context);
|
||||
publicKey = keySelector.getPublicKey();
|
||||
subjectKeyIdentifier = getKeyName(doc);
|
||||
} catch (MarshalException e) {
|
||||
LOGGER.warn("Error while unmarshalling XML signature: " + e.getMessage());
|
||||
} catch (XMLSignatureException e) {
|
||||
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) {
|
||||
LOGGER.warn(e.getMessage());
|
||||
LOGGER.info(e.getMessage());
|
||||
}
|
||||
|
||||
return isValid;
|
||||
@ -222,7 +233,12 @@ public class ReferenceManifestValidator {
|
||||
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 purpose purpose.
|
||||
@ -246,15 +262,23 @@ public class ReferenceManifestValidator {
|
||||
Object object = dataItr.next();
|
||||
if (object instanceof X509Certificate) {
|
||||
publicKey = ((X509Certificate) object).getPublicKey();
|
||||
if (areAlgorithmsEqual(algorithm.getAlgorithm(),
|
||||
publicKey.getAlgorithm())) {
|
||||
return new ReferenceManifestValidator.X509KeySelector
|
||||
.RIMKeySelectorResult(publicKey);
|
||||
}
|
||||
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(),
|
||||
publicKey.getAlgorithm())) {
|
||||
return new ReferenceManifestValidator.X509KeySelector
|
||||
.RIMKeySelectorResult(publicKey);
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user