From a57fb5a732ceba3592811f47b34a23d9e26e75da Mon Sep 17 00:00:00 2001 From: Berend Sliedrecht Date: Wed, 3 Jul 2024 15:11:07 +0200 Subject: [PATCH] fix(x509): use correct spki algorithm and parameters Signed-off-by: Berend Sliedrecht --- .../crypto/webcrypto/algorithmIdentifiers.ts | 42 +++++-------------- .../webcrypto/utils/keyAlgorithmConversion.ts | 22 +++++----- .../crypto/x509/__tests__/x509Service.test.ts | 12 ++++++ 3 files changed, 33 insertions(+), 43 deletions(-) diff --git a/packages/core/src/crypto/webcrypto/algorithmIdentifiers.ts b/packages/core/src/crypto/webcrypto/algorithmIdentifiers.ts index 7f7eb82f7..acb4a067a 100644 --- a/packages/core/src/crypto/webcrypto/algorithmIdentifiers.ts +++ b/packages/core/src/crypto/webcrypto/algorithmIdentifiers.ts @@ -1,51 +1,31 @@ -import { ecdsaWithSHA256 } from '@peculiar/asn1-ecc' -import { AsnProp, AsnPropTypes, AsnSerializer } from '@peculiar/asn1-schema' +import { id_ecPublicKey, id_secp256r1, id_secp384r1 } from '@peculiar/asn1-ecc' +import { AsnObjectIdentifierConverter } from '@peculiar/asn1-schema' import { AlgorithmIdentifier } from '@peculiar/asn1-x509' +const ecPublicKeyAlgorithmIdentifier = (objectId: string) => + new AlgorithmIdentifier({ + algorithm: id_ecPublicKey, + parameters: AsnObjectIdentifierConverter.toASN(objectId).toBER(), + }) + /** * * https://oid-rep.orange-labs.fr/get/1.2.840.10045.3.1.7 * */ -class P256AlgorithmIdentifierParameters { - @AsnProp({ type: AsnPropTypes.ObjectIdentifier }) - public parameters: string = '1.2.840.10045.3.1.7' -} - +export const ecPublicKeyWithP256AlgorithmIdentifier = ecPublicKeyAlgorithmIdentifier(id_secp256r1) /** * * https://oid-rep.orange-labs.fr/get/1.3.132.0.34 * */ -class P384AlgorithmIdentifierParameters { - @AsnProp({ type: AsnPropTypes.ObjectIdentifier }) - public parameters: string = '1.3.132.0.34' -} - +export const ecPublicKeyWithP384AlgorithmIdentifier = ecPublicKeyAlgorithmIdentifier(id_secp384r1) /** * * https://oid-rep.orange-labs.fr/get/1.3.132.0.10 * */ -class K256AlgorithmIdentifierParameters { - @AsnProp({ type: AsnPropTypes.ObjectIdentifier }) - public parameters: string = '1.3.132.0.10' -} - -export const ecdsaWithSha256AndP256AlgorithmIdentifier = new AlgorithmIdentifier({ - algorithm: ecdsaWithSHA256.algorithm, - parameters: AsnSerializer.serialize(new P256AlgorithmIdentifierParameters()), -}) - -export const ecdsaWithSha256AndK256AlgorithmIdentifier = new AlgorithmIdentifier({ - algorithm: ecdsaWithSHA256.algorithm, - parameters: AsnSerializer.serialize(new K256AlgorithmIdentifierParameters()), -}) - -export const ecdsaWithSha256AndP384AlgorithmIdentifier = new AlgorithmIdentifier({ - algorithm: ecdsaWithSHA256.algorithm, - parameters: AsnSerializer.serialize(new P384AlgorithmIdentifierParameters()), -}) +export const ecPublicKeyWithK256AlgorithmIdentifier = ecPublicKeyAlgorithmIdentifier('1.3.132.0.10') /** * diff --git a/packages/core/src/crypto/webcrypto/utils/keyAlgorithmConversion.ts b/packages/core/src/crypto/webcrypto/utils/keyAlgorithmConversion.ts index d475912ad..0acbba413 100644 --- a/packages/core/src/crypto/webcrypto/utils/keyAlgorithmConversion.ts +++ b/packages/core/src/crypto/webcrypto/utils/keyAlgorithmConversion.ts @@ -1,14 +1,12 @@ import type { EcKeyGenParams, KeyGenAlgorithm } from '../types' import type { AlgorithmIdentifier } from '@peculiar/asn1-x509' -import { ecdsaWithSHA256 } from '@peculiar/asn1-ecc' - import { KeyType } from '../../KeyType' import { CredoWebCryptoError } from '../CredoWebCryptoError' import { - ecdsaWithSha256AndK256AlgorithmIdentifier, - ecdsaWithSha256AndP256AlgorithmIdentifier, - ecdsaWithSha256AndP384AlgorithmIdentifier, + ecPublicKeyWithK256AlgorithmIdentifier, + ecPublicKeyWithP256AlgorithmIdentifier, + ecPublicKeyWithP384AlgorithmIdentifier, ed25519AlgorithmIdentifier, x25519AlgorithmIdentifier, } from '../algorithmIdentifiers' @@ -37,16 +35,16 @@ export const cryptoKeyAlgorithmToCredoKeyType = (algorithm: KeyGenAlgorithm): Ke } export const spkiAlgorithmIntoCredoKeyType = (algorithm: AlgorithmIdentifier): KeyType => { - if (algorithm.isEqual(ecdsaWithSha256AndP256AlgorithmIdentifier)) { + if (algorithm.isEqual(ecPublicKeyWithP256AlgorithmIdentifier)) { return KeyType.P256 - } else if (algorithm.isEqual(ecdsaWithSha256AndK256AlgorithmIdentifier)) { + } else if (algorithm.isEqual(ecPublicKeyWithP384AlgorithmIdentifier)) { + return KeyType.P384 + } else if (algorithm.isEqual(ecPublicKeyWithK256AlgorithmIdentifier)) { return KeyType.K256 } else if (algorithm.isEqual(ed25519AlgorithmIdentifier)) { return KeyType.Ed25519 } else if (algorithm.isEqual(x25519AlgorithmIdentifier)) { return KeyType.X25519 - } else if (algorithm.isEqual(ecdsaWithSHA256)) { - throw new CredoWebCryptoError(`ecdsa with SHA256 was used. Please specify a curve in algorithm parameters`) } throw new CredoWebCryptoError( @@ -61,11 +59,11 @@ export const credoKeyTypeIntoSpkiAlgorithm = (keyType: KeyType): AlgorithmIdenti case KeyType.X25519: return x25519AlgorithmIdentifier case KeyType.P256: - return ecdsaWithSha256AndP256AlgorithmIdentifier + return ecPublicKeyWithP256AlgorithmIdentifier case KeyType.P384: - return ecdsaWithSha256AndP384AlgorithmIdentifier + return ecPublicKeyWithP384AlgorithmIdentifier case KeyType.K256: - return ecdsaWithSha256AndK256AlgorithmIdentifier + return ecPublicKeyWithK256AlgorithmIdentifier default: throw new CredoWebCryptoError(`Unsupported key type: ${keyType}`) } diff --git a/packages/core/src/crypto/x509/__tests__/x509Service.test.ts b/packages/core/src/crypto/x509/__tests__/x509Service.test.ts index 228e07f43..871f11e91 100644 --- a/packages/core/src/crypto/x509/__tests__/x509Service.test.ts +++ b/packages/core/src/crypto/x509/__tests__/x509Service.test.ts @@ -119,6 +119,18 @@ describe('X509Service', () => { await wallet.close() }) + it('should correctly parse x5c chain provided as a test-vector', async () => { + const x5c = [ + 'MIICaTCCAg+gAwIBAgIUShyxcIZGiPV3wBRp4YOlNp1I13YwCgYIKoZIzj0EAwIwgYkxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZiZHIuZGUxDzANBgNVBAcMBkJlcmxpbjEMMAoGA1UECgwDQkRSMQ8wDQYDVQQLDAZNYXVyZXIxHTAbBgNVBAMMFGlzc3VhbmNlLXRlc3QuYmRyLmRlMRowGAYJKoZIhvcNAQkBFgt0ZXN0QGJkci5kZTAeFw0yNDA1MjgwODIyMjdaFw0zNDA0MDYwODIyMjdaMIGJMQswCQYDVQQGEwJERTEPMA0GA1UECAwGYmRyLmRlMQ8wDQYDVQQHDAZCZXJsaW4xDDAKBgNVBAoMA0JEUjEPMA0GA1UECwwGTWF1cmVyMR0wGwYDVQQDDBRpc3N1YW5jZS10ZXN0LmJkci5kZTEaMBgGCSqGSIb3DQEJARYLdGVzdEBiZHIuZGUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASygZ1Ma0m9uif4n8g3CiCP+E1r2KWFxVmS6LRWqUBMgn5fODKIBftdzVSbv/38gujy5qxh/q5bLcT+yLilazCao1MwUTAdBgNVHQ4EFgQUMGdPNMIdo3iHfqt2jlTnBNCfRNAwHwYDVR0jBBgwFoAUMGdPNMIdo3iHfqt2jlTnBNCfRNAwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiAu2h5xulXReb5IhgpkYiYR1BONTtsjT7nfzQAhL4ISOQIhAK6jKwwf6fTTSZwvJUOAu7dz1Dy/DmH19Lef0zqaNNht', + ] + + const chain = await X509Service.validateCertificateChain(agentContext, { certificateChain: x5c }) + + expect(chain.length).toStrictEqual(1) + expect(chain[0].sanDnsNames).toStrictEqual([]) + expect(chain[0].sanUriNames).toStrictEqual([]) + }) + it('should parse a valid X.509 certificate', async () => { const key = await agentContext.wallet.createKey({ keyType: KeyType.P256 }) const certificate = await X509Service.createSelfSignedCertificate(agentContext, {