Remove private/public key match verification.

Signed-off-by: Max Lambrecht <maxlambrecht@gmail.com>
This commit is contained in:
Max Lambrecht 2021-02-02 21:06:55 -03:00
parent 45e3fc86a6
commit 3049810a35
3 changed files with 8 additions and 79 deletions

View File

@ -10,10 +10,6 @@ import java.security.InvalidKeyException;
import java.security.KeyFactory; import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.CertPathValidator; import java.security.cert.CertPathValidator;
import java.security.cert.CertPathValidatorException; import java.security.cert.CertPathValidatorException;
import java.security.cert.Certificate; import java.security.cert.Certificate;
@ -44,10 +40,6 @@ import static org.apache.commons.lang3.StringUtils.startsWith;
*/ */
public class CertificateUtils { public class CertificateUtils {
// Algorithms for verifying private and public keys
private static final String SHA_512_WITH_ECDSA = "SHA512withECDSA";
private static final String SHA_512_WITH_RSA = "SHA512withRSA";
private static final String SPIFFE_PREFIX = "spiffe://"; private static final String SPIFFE_PREFIX = "spiffe://";
private static final int SAN_VALUE_INDEX = 1; private static final int SAN_VALUE_INDEX = 1;
private static final String PUBLIC_KEY_INFRASTRUCTURE_ALGORITHM = "PKIX"; private static final String PUBLIC_KEY_INFRASTRUCTURE_ALGORITHM = "PKIX";
@ -154,24 +146,6 @@ public class CertificateUtils {
return spiffeId.getTrustDomain(); return spiffeId.getTrustDomain();
} }
/**
* Validates that the private key and the public key in the x509Certificate match by
* creating a signature with the private key and verifying with the public key.
*
* @throws InvalidKeyException if the keys don't match
*/
public static void validatePrivateKey(final PrivateKey privateKey, final X509Certificate x509Certificate) throws InvalidKeyException {
AsymmetricKeyAlgorithm algorithm = AsymmetricKeyAlgorithm.parse(privateKey.getAlgorithm());
switch (algorithm) {
case RSA:
verifyKeys(privateKey, x509Certificate.getPublicKey(), SHA_512_WITH_RSA);
break;
case EC:
verifyKeys(privateKey, x509Certificate.getPublicKey(), SHA_512_WITH_ECDSA);
}
}
public static boolean isCA(final X509Certificate cert) { public static boolean isCA(final X509Certificate cert) {
return cert.getBasicConstraints() != -1; return cert.getBasicConstraints() != -1;
} }
@ -202,23 +176,6 @@ public class CertificateUtils {
return keySpec; return keySpec;
} }
private static void verifyKeys(final PrivateKey privateKey, final PublicKey publicKey, final String algorithm) throws InvalidKeyException {
final byte[] challenge = new SecureRandom().generateSeed(100);
try {
Signature sig = Signature.getInstance(algorithm);
sig.initSign(privateKey);
sig.update(challenge);
byte[] signature = sig.sign();
sig.initVerify(publicKey);
sig.update(challenge);
if (!sig.verify(signature)) {
throw new InvalidKeyException("Private Key does not match Certificate Public Key");
}
} catch (NoSuchAlgorithmException | SignatureException e) {
throw new InvalidKeyException("Private and Public Keys could not be verified", e);
}
}
private static List<String> getSpiffeIds(final X509Certificate certificate) throws CertificateParsingException { private static List<String> getSpiffeIds(final X509Certificate certificate) throws CertificateParsingException {
if (certificate.getSubjectAlternativeNames() == null) { if (certificate.getSubjectAlternativeNames() == null) {
return Collections.emptyList(); return Collections.emptyList();

View File

@ -145,7 +145,6 @@ public class X509Svid {
val privateKey = generatePrivateKey(privateKeyBytes, keyFileFormat, x509Certificates); val privateKey = generatePrivateKey(privateKeyBytes, keyFileFormat, x509Certificates);
val spiffeId = getSpiffeId(x509Certificates); val spiffeId = getSpiffeId(x509Certificates);
validatePrivateKey(privateKey, x509Certificates);
validateLeafCertificate(x509Certificates.get(0)); validateLeafCertificate(x509Certificates.get(0));
// there are intermediate CA certificates // there are intermediate CA certificates
@ -225,13 +224,4 @@ public class X509Svid {
throw new X509SvidException("Leaf certificate must not have 'cRLSign' as key usage"); throw new X509SvidException("Leaf certificate must not have 'cRLSign' as key usage");
} }
} }
private static void validatePrivateKey(final PrivateKey privateKey, final List<X509Certificate> x509Certificates)
throws X509SvidException {
try {
CertificateUtils.validatePrivateKey(privateKey, x509Certificates.get(0));
} catch (InvalidKeyException e) {
throw new X509SvidException("Private Key does not match Certificate Public Key", e);
}
}
} }

View File

@ -24,10 +24,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
public class X509SvidTest { class X509SvidTest {
static String keyRSA = "testdata/x509svid/key-pkcs8-rsa.pem"; static String keyRSA = "testdata/x509svid/key-pkcs8-rsa.pem";
static String keyRSAOther = "testdata/x509svid/key-rsa-other.pem";
static String certSingle = "testdata/x509svid/good-leaf-only.pem"; static String certSingle = "testdata/x509svid/good-leaf-only.pem";
static String leafNoDigitalSignature = "testdata/x509svid/wrong-leaf-no-digital-signature.pem"; static String leafNoDigitalSignature = "testdata/x509svid/wrong-leaf-no-digital-signature.pem";
static String leafCRLSign = "testdata/x509svid/wrong-leaf-crl-sign.pem"; static String leafCRLSign = "testdata/x509svid/wrong-leaf-crl-sign.pem";
@ -39,7 +38,6 @@ public class X509SvidTest {
static String keyECDSA = "testdata/x509svid/key-pkcs8-ecdsa.pem"; static String keyECDSA = "testdata/x509svid/key-pkcs8-ecdsa.pem";
static String certMultiple = "testdata/x509svid/good-leaf-and-intermediate.pem"; static String certMultiple = "testdata/x509svid/good-leaf-and-intermediate.pem";
static String corrupted = "testdata/x509svid/corrupted"; static String corrupted = "testdata/x509svid/corrupted";
static String keyECDSAOther = "testdata/x509svid/key-ecdsa-other.pem";
static String keyDER = "testdata/x509svid/keyEC.der"; static String keyDER = "testdata/x509svid/keyEC.der";
static String certDER = "testdata/x509svid/cert.der"; static String certDER = "testdata/x509svid/cert.der";
@ -99,23 +97,7 @@ public class X509SvidTest {
), ),
Arguments.of(TestCase Arguments.of(TestCase
.builder() .builder()
.name("7. Certificate does not match private key: RSA keys") .name("7. Certificate without SPIFFE ID")
.certsPath(certSingle)
.keyPath(keyRSAOther)
.expectedError("Private Key does not match Certificate Public Key")
.build()
),
Arguments.of(TestCase
.builder()
.name("8. Certificate does not match private key: EC keys")
.certsPath(certMultiple)
.keyPath(keyECDSAOther)
.expectedError("Private Key does not match Certificate Public Key")
.build()
),
Arguments.of(TestCase
.builder()
.name("9. Certificate without SPIFFE ID")
.certsPath(leafEmptyID) .certsPath(leafEmptyID)
.keyPath(keyRSA) .keyPath(keyRSA)
.expectedError("Certificate does not contain SPIFFE ID in the URI SAN") .expectedError("Certificate does not contain SPIFFE ID in the URI SAN")
@ -123,7 +105,7 @@ public class X509SvidTest {
), ),
Arguments.of(TestCase Arguments.of(TestCase
.builder() .builder()
.name("10. Leaf certificate with CA flag set to true") .name("8. Leaf certificate with CA flag set to true")
.certsPath(leafCAtrue) .certsPath(leafCAtrue)
.keyPath(keyRSA) .keyPath(keyRSA)
.expectedError("Leaf certificate must not have CA flag set to true") .expectedError("Leaf certificate must not have CA flag set to true")
@ -131,7 +113,7 @@ public class X509SvidTest {
), ),
Arguments.of(TestCase Arguments.of(TestCase
.builder() .builder()
.name("11. Leaf certificate without digitalSignature as key usage") .name("9. Leaf certificate without digitalSignature as key usage")
.certsPath(leafNoDigitalSignature) .certsPath(leafNoDigitalSignature)
.keyPath(keyRSA) .keyPath(keyRSA)
.expectedError("Leaf certificate must have 'digitalSignature' as key usage") .expectedError("Leaf certificate must have 'digitalSignature' as key usage")
@ -139,7 +121,7 @@ public class X509SvidTest {
), ),
Arguments.of(TestCase Arguments.of(TestCase
.builder() .builder()
.name("12. Leaf certificate with certSign as key usage") .name("10. Leaf certificate with certSign as key usage")
.certsPath(leafCertSign) .certsPath(leafCertSign)
.keyPath(keyRSA) .keyPath(keyRSA)
.expectedError("Leaf certificate must not have 'keyCertSign' as key usage") .expectedError("Leaf certificate must not have 'keyCertSign' as key usage")
@ -147,7 +129,7 @@ public class X509SvidTest {
), ),
Arguments.of(TestCase Arguments.of(TestCase
.builder() .builder()
.name("13. Leaf certificate with cRLSign as key usage") .name("11. Leaf certificate with cRLSign as key usage")
.certsPath(leafCRLSign) .certsPath(leafCRLSign)
.keyPath(keyRSA) .keyPath(keyRSA)
.expectedError("Leaf certificate must not have 'cRLSign' as key usage") .expectedError("Leaf certificate must not have 'cRLSign' as key usage")
@ -155,7 +137,7 @@ public class X509SvidTest {
), ),
Arguments.of(TestCase Arguments.of(TestCase
.builder() .builder()
.name("14. Signing certificate without CA flag") .name("12. Signing certificate without CA flag")
.certsPath(signNoCA) .certsPath(signNoCA)
.keyPath(keyRSA) .keyPath(keyRSA)
.expectedError("Signing certificate must have CA flag set to true") .expectedError("Signing certificate must have CA flag set to true")
@ -163,7 +145,7 @@ public class X509SvidTest {
), ),
Arguments.of(TestCase Arguments.of(TestCase
.builder() .builder()
.name("15. Signing certificate without CA flag") .name("13. Signing certificate without CA flag")
.certsPath(signNoKeyCertSign) .certsPath(signNoKeyCertSign)
.keyPath(keyRSA) .keyPath(keyRSA)
.expectedError("Signing certificate must have 'keyCertSign' as key usage") .expectedError("Signing certificate must have 'keyCertSign' as key usage")