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

Add java example #1

Merged
merged 12 commits into from
Sep 6, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
import com.fortanix.keyattestationstatementverifier.Common;
import com.fortanix.keyattestationstatementverifier.KeyAttestationStatementVerifyException;
import com.fortanix.keyattestationstatementverifier.types.asn1.ClusterNodeEnrollmentPolicy;
import com.fortanix.keyattestationstatementverifier.types.asn1.KeyUsage;
import com.fortanix.keyattestationstatementverifier.types.asn1.KeyUsageExt;
import com.fortanix.keyattestationstatementverifier.types.asn1.NodeEnrollmentPolicyItem;
import com.fortanix.keyattestationstatementverifier.types.asn1.KeyUsageExt.KeyUsage;

public class DsmKeyAttestationAuthorityCertChecker extends CertChecker {
private static final Logger LOGGER = Logger.getLogger(DsmKeyAttestationAuthorityCertChecker.class.getName());
Expand Down Expand Up @@ -76,8 +77,13 @@ private void check_extensions(X509Certificate cert, X509Certificate issuerCert)
LOGGER.info(String.format(
"Checking '%s' certificate's KeyUsages extension", certCN));
KeyUsage[] authorityCertExpectedKeyUsage = { KeyUsage.DIGITAL_SIGNATURE };
KeyUsage.checkKeyUsageHelper(Common.DSM_CLUSTER_KEY_ATTESTATION_AUTHORITY_CN, cert.getKeyUsage(),
authorityCertExpectedKeyUsage);
KeyUsageExt keyUsageExt = new KeyUsageExt(cert.getKeyUsage());
if (!keyUsageExt.hasUsage(authorityCertExpectedKeyUsage)) {
throw new KeyAttestationStatementVerifyException(
Common.DSM_CLUSTER_KEY_ATTESTATION_AUTHORITY_CN
+ " certificate keyUsage extension should contains: "
+ authorityCertExpectedKeyUsage.toString());
}
// check extension: Basic Constraints
LOGGER.info(String.format(
"Checking '%s' certificate's BasicConstraints extension", certCN));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@

import com.fortanix.keyattestationstatementverifier.Common;
import com.fortanix.keyattestationstatementverifier.KeyAttestationStatementVerifyException;
import com.fortanix.keyattestationstatementverifier.types.asn1.KeyUsage;
import com.fortanix.keyattestationstatementverifier.types.asn1.KeyUsageExt;
import com.fortanix.keyattestationstatementverifier.types.asn1.KeyUsageExt.KeyUsage;

public class FortanixRootCertChecker extends CertChecker {
private static final Logger LOGGER = Logger.getLogger(FortanixRootCertChecker.class.getName());
Expand Down Expand Up @@ -72,8 +73,13 @@ private void check_extensions(X509Certificate cert) throws Exception {
LOGGER.info(String.format(
"Checking '%s' certificate's KeyUsages extension", certCN));
KeyUsage[] rootCertExpectedKeyUsage = { KeyUsage.DIGITAL_SIGNATURE, KeyUsage.KEY_CERT_SIGN, KeyUsage.CRL_SIGN };
KeyUsage.checkKeyUsageHelper(Common.FORTANIX_ATTESTATION_AND_PROVISIONING_ROOT_CA_CN, cert.getKeyUsage(),
rootCertExpectedKeyUsage);
KeyUsageExt keyUsageExt = new KeyUsageExt(cert.getKeyUsage());
if (!keyUsageExt.hasUsage(rootCertExpectedKeyUsage)) {
throw new KeyAttestationStatementVerifyException(
Common.FORTANIX_ATTESTATION_AND_PROVISIONING_ROOT_CA_CN
+ " certificate keyUsage extension should contains: "
+ rootCertExpectedKeyUsage.toString());
}
int pathLenConstraint = cert.getBasicConstraints();
// check extension: Basic Constraints
LOGGER.info(String.format(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@

import com.fortanix.keyattestationstatementverifier.Common;
import com.fortanix.keyattestationstatementverifier.KeyAttestationStatementVerifyException;
import com.fortanix.keyattestationstatementverifier.types.asn1.KeyUsage;
import com.fortanix.keyattestationstatementverifier.types.asn1.KeyUsageExt;
import com.fortanix.keyattestationstatementverifier.types.asn1.KeyUsageExt.KeyUsage;

public class KeyAttestationCaCertChecker extends CertChecker {
private static final Logger LOGGER = Logger.getLogger(KeyAttestationCaCertChecker.class.getName());
Expand Down Expand Up @@ -75,8 +76,13 @@ private void check_extensions(X509Certificate cert, X509Certificate issuerCert)
LOGGER.info(String.format(
"Checking '%s' certificate's KeyUsages extension", certCN));
KeyUsage[] caCertExpectedKeyUsage = { KeyUsage.DIGITAL_SIGNATURE, KeyUsage.KEY_CERT_SIGN, KeyUsage.CRL_SIGN };
KeyUsage.checkKeyUsageHelper(Common.FORTANIX_KEY_ATTESTATION_CA_CN, cert.getKeyUsage(),
caCertExpectedKeyUsage);
KeyUsageExt keyUsageExt = new KeyUsageExt(cert.getKeyUsage());
if (!keyUsageExt.hasUsage(caCertExpectedKeyUsage)) {
throw new KeyAttestationStatementVerifyException(
Common.FORTANIX_KEY_ATTESTATION_CA_CN
+ " certificate keyUsage extension should contains: "
+ caCertExpectedKeyUsage.toString());
}
// check extension: Basic Constraints
LOGGER.info(String.format(
"Checking '%s' certificate's BasicConstraints extension", certCN));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@

import com.fortanix.keyattestationstatementverifier.Common;
import com.fortanix.keyattestationstatementverifier.KeyAttestationStatementVerifyException;
import com.fortanix.keyattestationstatementverifier.types.asn1.KeyUsage;
import com.fortanix.keyattestationstatementverifier.types.asn1.KeyUsageExt;
import com.fortanix.keyattestationstatementverifier.types.asn1.KeyUsageExt.KeyUsage;

public class KeyAttestationStatementCertChecker extends CertChecker {
private static final Logger LOGGER = Logger.getLogger(KeyAttestationStatementCertChecker.class.getName());
Expand Down Expand Up @@ -57,7 +58,7 @@ private void check_extensions(X509Certificate cert, X509Certificate issuerCert)
checkCertKeyUsages(cert);
// check extension: Authority Key Identifier
LOGGER.info(String.format(
"Checking '%s' certificate's AuthorityKeyIdentifier extension", certCN));
"Checking '%s' certificate's AuthorityKeyIdentifier extension", certCN));
if (!Arrays.equals(getExtAkiVal(cert), getExtSkiVal(issuerCert))) {
throw new KeyAttestationStatementVerifyException(
Common.KEY_ATTESTATION_STATEMENT_CN
Expand All @@ -68,29 +69,24 @@ private void check_extensions(X509Certificate cert, X509Certificate issuerCert)
private void checkCertKeyUsages(X509Certificate cert) throws KeyAttestationStatementVerifyException {
LOGGER.info(String.format(
"Checking '%s' certificate's KeyUsages extension", certCN));
boolean[] certKeyUsagesBooleans = cert.getKeyUsage();
if (certKeyUsagesBooleans != null && certKeyUsagesBooleans.length == 9) {
KeyUsage[] allowedKeyUsages = {
KeyUsage.DIGITAL_SIGNATURE,
KeyUsage.KEY_ENCIPHERMENT,
KeyUsage.DATA_ENCIPHERMENT,
KeyUsage.KEY_AGREEMENT,
};
Set<KeyUsage> allowedKeyUsagesSet = Arrays.stream(allowedKeyUsages).collect(Collectors.toSet());
KeyUsageExt keyUsageExt = new KeyUsageExt(cert.getKeyUsage());
KeyUsage[] allowedKeyUsages = {
KeyUsage.DIGITAL_SIGNATURE,
KeyUsage.KEY_ENCIPHERMENT,
KeyUsage.DATA_ENCIPHERMENT,
KeyUsage.KEY_AGREEMENT,
};
Set<KeyUsage> allowedKeyUsagesSet = Arrays.stream(allowedKeyUsages).collect(Collectors.toSet());

KeyUsage[] disallowedKeyUsages = Arrays.stream(KeyUsage.values())
.filter(keyUsage -> !allowedKeyUsagesSet.contains(keyUsage))
.toArray(KeyUsage[]::new);
for (KeyUsage ku : disallowedKeyUsages) {
if (certKeyUsagesBooleans[ku.getBitIndex()]) {
throw new KeyAttestationStatementVerifyException(
Common.KEY_ATTESTATION_STATEMENT_CN + " keyUsage extension should not contain: "
+ ku.toString());
}
KeyUsage[] disallowedKeyUsages = Arrays.stream(KeyUsage.values())
.filter(keyUsage -> !allowedKeyUsagesSet.contains(keyUsage))
.toArray(KeyUsage[]::new);
for (KeyUsage ku : disallowedKeyUsages) {
if (keyUsageExt.hasUsage(ku)) {
throw new KeyAttestationStatementVerifyException(
Common.KEY_ATTESTATION_STATEMENT_CN + " keyUsage extension should not contain: "
+ ku.toString());
}
} else {
throw new KeyAttestationStatementVerifyException(
Common.KEY_ATTESTATION_STATEMENT_CN + " invalid keyUsage extension");
}
}
}
xinyufort marked this conversation as resolved.
Outdated
Show resolved Hide resolved

This file was deleted.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wow, you actually created a new KeyUsageExt type 😲

Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.fortanix.keyattestationstatementverifier.types.asn1;

import java.util.Arrays;
import java.util.EnumSet;

import com.fortanix.keyattestationstatementverifier.KeyAttestationStatementVerifyException;

/**
* The helper type for checking X509 KeyUsage extension
*/
public class KeyUsageExt {
public enum KeyUsage {
DIGITAL_SIGNATURE(0),
NON_REPUDIATION(1),
KEY_ENCIPHERMENT(2),
DATA_ENCIPHERMENT(3),
KEY_AGREEMENT(4),
KEY_CERT_SIGN(5),
CRL_SIGN(6),
ENCIPHER_ONLY(7),
DECIPHER_ONLY(8);

final int bitIndex;

private KeyUsage(int bitIndex) {
this.bitIndex = bitIndex;
}

public int getBitIndex() {
return this.bitIndex;
}

@Override
public String toString() {
switch (this) {
case DIGITAL_SIGNATURE:
return "Digital Signature";
case NON_REPUDIATION:
return "Non-Repudiation";
case KEY_ENCIPHERMENT:
return "Key Encipherment";
case DATA_ENCIPHERMENT:
return "Data Encipherment";
case KEY_AGREEMENT:
return "Key Agreement";
case KEY_CERT_SIGN:
return "Key Certificate Sign";
case CRL_SIGN:
return "CRL Sign";
case ENCIPHER_ONLY:
return "Encipher Only";
case DECIPHER_ONLY:
return "Decipher Only";
default:
throw new IllegalArgumentException();
}
}
}

private final EnumSet<KeyUsage> usages = EnumSet.noneOf(KeyUsage.class);

public KeyUsageExt(boolean[] keyUsageBitArray) {
if (keyUsageBitArray.length != KeyUsage.values().length) {
throw new IllegalArgumentException("Invalid length of keyUsageBitArray");
}

KeyUsage[] usages = KeyUsage.values();
for (int i = 0; i < keyUsageBitArray.length; i++) {
if (keyUsageBitArray[i]) {
this.usages.add(usages[i]);
}
}
}

public boolean hasUsage(KeyUsage keyUsage) {
return usages.contains(keyUsage);
}

public boolean hasUsage(KeyUsage[] keyUsageList) {
return usages.containsAll(Arrays.asList(keyUsageList));
}

@Override
public String toString() {
return "KeyUsageExt{" + usages + '}';
}
}
Loading