diff --git a/packages/did-provider-key/src/SphereonKeyDidProvider.ts b/packages/did-provider-key/src/SphereonKeyDidProvider.ts index 68ffa7de..0a1773d2 100644 --- a/packages/did-provider-key/src/SphereonKeyDidProvider.ts +++ b/packages/did-provider-key/src/SphereonKeyDidProvider.ts @@ -5,7 +5,7 @@ import { jwkJcsEncode, JwkKeyUse, TKeyType, - toJwk, + toJwk, toRawCompressedHexPublicKey, } from '@sphereon/ssi-sdk-ext.key-utils' import { IAgentContext, IIdentifier, IKey, IKeyManager, IService } from '@veramo/core' import { AbstractIdentifierProvider } from '@veramo/did-manager' @@ -70,6 +70,9 @@ export class SphereonKeyDidProvider extends AbstractIdentifierProvider { ) let methodSpecificId: string | undefined + + // did:key uses compressed pub keys + const compressedPublicKeyHex = toRawCompressedHexPublicKey(u8a.fromString(key.publicKeyHex, 'hex'), key.type) if (codecName === JWK_JCS_PUB_NAME) { const jwk = toJwk(key.publicKeyHex, keyType, { use: JwkKeyUse.Signature, key, noKidThumbprint: true }) // console.log(`FIXME JWK: ${JSON.stringify(toJwk(privateKeyHex, keyType, { use: JwkKeyUse.Signature, key, isPrivateKey: true }), null, 2)}`) @@ -78,7 +81,7 @@ export class SphereonKeyDidProvider extends AbstractIdentifierProvider { ) } else if (codecName) { methodSpecificId = u8a.toString( - Multibase.encode('base58btc', Multicodec.addPrefix(codecName as Multicodec.CodecName, u8a.fromString(key.publicKeyHex, 'hex'))) + Multibase.encode('base58btc', Multicodec.addPrefix(codecName as Multicodec.CodecName, u8a.fromString(compressedPublicKeyHex, 'hex'))) ) } else { codecName = keyCodecs[keyType] @@ -86,7 +89,7 @@ export class SphereonKeyDidProvider extends AbstractIdentifierProvider { if (codecName) { // methodSpecificId = bytesToMultibase({bytes: u8a.fromString(key.publicKeyHex, 'hex'), codecName}) methodSpecificId = u8a - .toString(Multibase.encode('base58btc', Multicodec.addPrefix(codecName as Multicodec.CodecName, u8a.fromString(key.publicKeyHex, 'hex')))) + .toString(Multibase.encode('base58btc', Multicodec.addPrefix(codecName as Multicodec.CodecName, u8a.fromString(compressedPublicKeyHex, 'hex')))) .toString() } } diff --git a/packages/key-utils/src/functions.ts b/packages/key-utils/src/functions.ts index 70add634..69510ef0 100644 --- a/packages/key-utils/src/functions.ts +++ b/packages/key-utils/src/functions.ts @@ -491,7 +491,7 @@ export const isRawCompressedPublicKey = (key: Uint8Array): boolean => key.length export const toRawCompressedHexPublicKey = (rawPublicKey: Uint8Array, keyType: TKeyType): string => { if (isRawCompressedPublicKey(rawPublicKey)) { - throw new Error('Invalid public key format, an uncompressed raw public key is required as input, not a raw') + return hexStringFromUint8Array(rawPublicKey) } if (keyType === 'Secp256k1' || keyType === 'Secp256r1') { diff --git a/packages/x509-utils/__tests__/functions.test.ts b/packages/x509-utils/__tests__/functions.test.ts index d7027244..07488857 100644 --- a/packages/x509-utils/__tests__/functions.test.ts +++ b/packages/x509-utils/__tests__/functions.test.ts @@ -17,23 +17,25 @@ const sphereonCA = const sphereonTest = '-----BEGIN CERTIFICATE-----\n' + - 'MIIC1jCCAnygAwIBAgITALtvb+InWBtzJO3mAeQZIUBXbzAKBggqhkjOPQQDAjBa\n' + - 'MQswCQYDVQQGEwJOTDEkMCIGA1UECgwbU3BoZXJlb24gSW50ZXJuYXRpb25hbCBC\n' + - 'LlYuMQswCQYDVQQLDAJJVDEYMBYGA1UEAwwPY2Euc3BoZXJlb24uY29tMB4XDTI0\n' + - 'MDgwNjIwMTYxMloXDTI0MTEwNDIyMTYxMlowJDEiMCAGA1UEAwwZdGVzdDEyMy50\n' + - 'ZXN0LnNwaGVyZW9uLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKclR1Ue\n' + - 'yHYFphv0y29/iv+HYN1wuhkEFgwetS52teZ7OcVNCBD0kMmqEaKjbczwd2GvbV1A\n' + - 'OxgE7AKsa3L0zxOjggFVMIIBUTAdBgNVHQ4EFgQUoWVOwL15ttB1YPUd0HgvYry0\n' + - 'Z+UwHwYDVR0jBBgwFoAU5wfKXZVc+cig/s7jZEUegLMsMsEwYQYIKwYBBQUHAQEE\n' + - 'VTBTMFEGCCsGAQUFBzAChkVodHRwOi8vZXUuY2VydC5lemNhLmlvL2NlcnRzL2Rh\n' + - 'YTFiNGI0LTg1ZmQtNGJhNC1iOTZiLTMzMmFkZDg5OWNlOS5jZXIwEwYDVR0lBAww\n' + - 'CgYIKwYBBQUHAwIwJAYDVR0RBB0wG4IZdGVzdDEyMy50ZXN0LnNwaGVyZW9uLmNv\n' + - 'bTAOBgNVHQ8BAf8EBAMCB4AwYQYDVR0fBFowWDBWoFSgUoZQaHR0cDovL2V1LmNy\n' + - 'bC5lemNhLmlvL2NybC8yY2RmN2M1ZS1iOWNkLTQzMTctYmI1Ni0zODZkMjQ0Mzgw\n' + - 'ZTIvY2FzcGhlcmVvbmNvbS5jcmwwCgYIKoZIzj0EAwIDSAAwRQIgThuggyhKePvR\n' + - 't5YEvfg6MD42N2/63L0ypw0vLZkM+zYCIQD+uInjqsfR6K/D+ebjuOAdhOyeD2nZ\n' + - 'AW29zN20WIQJsw==\n' + - '-----END CERTIFICATE-----' + 'MIIDSDCCAu6gAwIBAgISK90y2oo7lOTaCgILZPsHpoI1MAoGCCqGSM49BAMCMFox\n' + + 'CzAJBgNVBAYTAk5MMSQwIgYDVQQKDBtTcGhlcmVvbiBJbnRlcm5hdGlvbmFsIEIu\n' + + 'Vi4xCzAJBgNVBAsMAklUMRgwFgYDVQQDDA9jYS5zcGhlcmVvbi5jb20wHhcNMjQx\n' + + 'MTI2MTk0OTMyWhcNMjUwMjI0MjE0OTMyWjCBjjELMAkGA1UEBhMCTkwxFjAUBgNV\n' + + 'BAgMDU5vb3JkLUhvbGxhbmQxEjAQBgNVBAcMCUFtc3RlcmRhbTEkMCIGA1UECgwb\n' + + 'U3BoZXJlb24gSW50ZXJuYXRpb25hbCBCLlYuMQswCQYDVQQLDAJJVDEgMB4GA1UE\n' + + 'AwwXZnVua2UuZGVtby5zcGhlcmVvbi5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB\n' + + 'BwNCAATfCH3q528xCDpTCHAd1bgjh5wytgU0qWKG4XOihHTpXyFW9budmWwOFioR\n' + + 'OIbSx1mN6En8E560QjlZzRknIzOzo4IBXTCCAVkwHQYDVR0OBBYEFIdPsQ39CfxO\n' + + 'JY1T2qlddg7Gwv6nMB8GA1UdIwQYMBaAFOcHyl2VXPnIoP7O42RFHoCzLDLBMGEG\n' + + 'CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL2V1LmNlcnQuZXpjYS5p\n' + + 'by9jZXJ0cy9kYWExYjRiNC04NWZkLTRiYTQtYjk2Yi0zMzJhZGQ4OTljZTkuY2Vy\n' + + 'MB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAiBgNVHREEGzAZghdmdW5r\n' + + 'ZS5kZW1vLnNwaGVyZW9uLmNvbTAOBgNVHQ8BAf8EBAMCBaAwYQYDVR0fBFowWDBW\n' + + 'oFSgUoZQaHR0cDovL2V1LmNybC5lemNhLmlvL2NybC8yY2RmN2M1ZS1iOWNkLTQz\n' + + 'MTctYmI1Ni0zODZkMjQ0MzgwZTIvY2FzcGhlcmVvbmNvbS5jcmwwCgYIKoZIzj0E\n' + + 'AwIDSAAwRQIhALz0V+89FVAIEamNEnXy/TP2bBJR5yE8i/1l4fhSeGdUAiAk8/1f\n' + + 'vlqgdD+DS48bBXK0s0ZfALgdAGO/jOttA+tLYg==\n' + + '-----END CERTIFICATE-----' const walletPEM = '-----BEGIN CERTIFICATE-----\n' + @@ -96,15 +98,14 @@ const funkeTestIssuer = const animoFunkeDER = 'MIH6MIGhoAMCAQICEDlbxpcN1V1PRbmc2TtPjNQwCgYIKoZIzj0EAwIwADAeFw03MDAxMDEwMDAwMDBaFw0yNTExMjIwODIyMTJaMAAwOTATBgcqhkjOPQIBBggqhkjOPQMBBwMiAALcD1XzKepFxWMAOqV+ln1fybBt7DRO5CV0f9A6mRp2xaMdMBswGQYDVR0RBBIwEIIOZnVua2UuYW5pbW8uaWQwCgYIKoZIzj0EAwIDSAAwRQIhAIFd2jlrZAzLTLsXdUE7O+CRuxuzk04lGo1eVYIbgT8iAiAQhR/FonhoLLTFjU/3tn5rPyB2DaOl3W18W5ugLWHjhQ==' -describe.skip('functions: validateX5cCertificateChain', () => { // FIXME SDK-46 +describe('functions: validateX5cCertificateChain', () => { // FIXME SDK-46 const validChain = [walletPEM, sphereonCA] const invalidChain = [externalTestCert, walletPEM, sphereonCA] - // TODO: Disabled as cert expired - xit('should validate a valid certificate chain without providing a CA as trust anchor, but with trustRoot enabled', async () => { + it('should validate a valid certificate chain without providing a CA as trust anchor, but with trustRoot enabled', async () => { const result = await validateX509CertificateChain({ - chain: [walletPEM, sphereonCA], + chain: [sphereonTest, sphereonCA ], opts: { trustRootWhenNoAnchors: true } /*, trustedCerts: [sphereonCA]*/, }) expect(result).toMatchObject({ @@ -257,13 +258,13 @@ describe.skip('functions: validateX5cCertificateChain', () => { // FIXME SDK-46 it('should validate with client id scheme x509_san_dns and san_uri', async () => { expect(() => - assertCertificateMatchesClientIdScheme(pemOrDerToX509Certificate(sphereonTest), 'test123.test.sphereon.com', 'x509_san_dns') + assertCertificateMatchesClientIdScheme(pemOrDerToX509Certificate(sphereonTest), 'funke.demo.sphereon.com', 'x509_san_dns') ).not.toThrow() expect(() => assertCertificateMatchesClientIdScheme(pemOrDerToX509Certificate(sphereonTest), 'nope.test.sphereon.com', 'x509_san_dns')).toThrow() // The extension san_uri is not in the cert, so should throw error in case the above validating clientid for san_dns is used but now for san_uri expect(() => - assertCertificateMatchesClientIdScheme(pemOrDerToX509Certificate(sphereonTest), 'test123.test.sphereon.com', 'x509_san_uri') + assertCertificateMatchesClientIdScheme(pemOrDerToX509Certificate(sphereonTest), 'funke.demo.sphereon.com', 'x509_san_uri') ).toThrow() }) })