UNPKG

@credo-ts/core

Version:

<p align="center"> <br /> <img alt="Credo Logo" src="https://github.com/openwallet-foundation/credo-ts/blob/c7886cb8377ceb8ee4efe8d264211e561a75072d/images/credo-logo.png" height="250px" /> </p> <h1 align="center"><b>Credo - Core</b></h1

1 lines • 11.7 kB
{"version":3,"file":"CertificateSigningRequest.mjs","names":[],"sources":["../../../src/modules/x509/CertificateSigningRequest.ts"],"sourcesContent":["import { AsnParser } from '@peculiar/asn1-schema'\nimport { SubjectPublicKeyInfo } from '@peculiar/asn1-x509'\nimport * as x509 from '@peculiar/x509'\nimport {\n CredoWebCrypto,\n CredoWebCryptoKey,\n jwaAlgorithmToKeySignParams,\n publicJwkToCryptoKeyAlgorithm,\n} from '../../crypto/webcrypto'\nimport { spkiToPublicJwk } from '../../crypto/webcrypto/utils'\nimport { PublicJwk } from '../kms'\nimport {\n convertName,\n createExtendedKeyUsagesExtension,\n createKeyUsagesExtension,\n createSubjectAlternativeNameExtension,\n createSubjectKeyIdentifierExtension,\n X509ExtensionIdentifier,\n} from './utils'\nimport { X509ExtendedKeyUsage, X509KeyUsage } from './X509Certificate'\nimport { X509Error } from './X509Error'\nimport type { X509CreateCertificateSigningRequestOptions } from './X509ServiceOptions'\n\nexport type CertificateSigningRequestOptions = {\n publicJwk: PublicJwk\n certificateRequest: x509.Pkcs10CertificateRequest\n}\n\nexport class CertificateSigningRequest {\n public publicJwk: PublicJwk\n private certificateRequest: x509.Pkcs10CertificateRequest\n\n private constructor(options: CertificateSigningRequestOptions) {\n this.publicJwk = options.publicJwk\n this.certificateRequest = options.certificateRequest\n }\n\n public set keyId(keyId: string) {\n this.publicJwk.keyId = keyId\n }\n\n public get keyId(): string {\n return this.publicJwk.keyId\n }\n\n public get hasKeyId(): boolean {\n return this.publicJwk.hasKeyId\n }\n\n public static fromRawCertificateRequest(rawCertificateRequest: Uint8Array): CertificateSigningRequest {\n const certificateRequest = new x509.Pkcs10CertificateRequest(rawCertificateRequest)\n return CertificateSigningRequest.parseCertificateRequest(certificateRequest)\n }\n\n public static fromEncodedCertificateRequest(encodedCertificateRequest: string): CertificateSigningRequest {\n const certificateRequest = new x509.Pkcs10CertificateRequest(encodedCertificateRequest)\n return CertificateSigningRequest.parseCertificateRequest(certificateRequest)\n }\n\n private static parseCertificateRequest(certificateRequest: x509.Pkcs10CertificateRequest): CertificateSigningRequest {\n const spki = AsnParser.parse(certificateRequest.publicKey.rawData, SubjectPublicKeyInfo)\n const publicJwk = spkiToPublicJwk(spki)\n\n return new CertificateSigningRequest({\n publicJwk,\n certificateRequest,\n })\n }\n\n private getMatchingExtensions<T = { critical: boolean }>(objectIdentifier: string): Array<T> | undefined {\n const matchingExtensions = this.certificateRequest.extensions.filter((e) => e.type === objectIdentifier)\n if (matchingExtensions.length === 0) return undefined\n return matchingExtensions as Array<T>\n }\n\n public get rawCertificateRequest() {\n return new Uint8Array(this.certificateRequest.rawData)\n }\n\n public get subjectAlternativeNames() {\n const san = this.getMatchingExtensions<x509.SubjectAlternativeNameExtension>(X509ExtensionIdentifier.SubjectAltName)\n return san?.flatMap((s) => s.names.items ?? []).map((i) => ({ type: i.type, value: i.value })) ?? []\n }\n\n public get sanDnsNames() {\n return this.subjectAlternativeNames.filter((san) => san.type === 'dns').map((san) => san.value)\n }\n\n public get sanUriNames() {\n return this.subjectAlternativeNames.filter((san) => san.type === 'url').map((san) => san.value)\n }\n\n public get subjectKeyIdentifier() {\n const keyIds = this.getMatchingExtensions<x509.SubjectKeyIdentifierExtension>(\n X509ExtensionIdentifier.SubjectKeyIdentifier\n )?.map((e) => e.keyId)\n\n if (keyIds && keyIds.length > 1) {\n throw new X509Error('Multiple Subject Key Identifiers are not allowed')\n }\n\n return keyIds?.[0]\n }\n\n public get keyUsage() {\n const keyUsages = this.getMatchingExtensions<x509.KeyUsagesExtension>(X509ExtensionIdentifier.KeyUsage)?.map(\n (e) => e.usages\n )\n\n if (keyUsages && keyUsages.length > 1) {\n throw new X509Error('Multiple Key Usages are not allowed')\n }\n\n if (keyUsages && keyUsages.length > 0) {\n return Object.values(X509KeyUsage)\n .filter((key): key is number => typeof key === 'number')\n .filter((flagValue) => (keyUsages[0] & flagValue) === flagValue)\n .map((flagValue) => flagValue as X509KeyUsage)\n }\n\n return []\n }\n\n public get extendedKeyUsage() {\n const extendedKeyUsages = this.getMatchingExtensions<x509.ExtendedKeyUsageExtension>(\n X509ExtensionIdentifier.ExtendedKeyUsage\n )?.map((e) => e.usages)\n\n if (extendedKeyUsages && extendedKeyUsages.length > 1) {\n throw new X509Error('Multiple Extended Key Usages are not allowed')\n }\n\n return (extendedKeyUsages?.[0] as Array<X509ExtendedKeyUsage> | undefined) ?? []\n }\n\n public isExtensionCritical(id: X509ExtensionIdentifier | string): boolean {\n const extension = this.getMatchingExtensions(id)\n if (!extension) {\n throw new X509Error(`extension with id '${id}' is not found`)\n }\n\n return !!extension[0].critical\n }\n\n public static async create(options: X509CreateCertificateSigningRequestOptions, webCrypto: CredoWebCrypto) {\n const signingKey = new CredoWebCryptoKey(\n options.subjectPublicKey,\n publicJwkToCryptoKeyAlgorithm(options.subjectPublicKey),\n false,\n 'private',\n ['sign']\n )\n const publicKey = new CredoWebCryptoKey(\n options.subjectPublicKey,\n publicJwkToCryptoKeyAlgorithm(options.subjectPublicKey),\n true,\n 'public',\n ['verify']\n )\n\n const extensions: Array<x509.Extension | undefined> = []\n extensions.push(\n createSubjectKeyIdentifierExtension(options.extensions?.subjectKeyIdentifier, {\n publicJwk: options.subjectPublicKey,\n })\n )\n extensions.push(createKeyUsagesExtension(options.extensions?.keyUsage))\n extensions.push(createExtendedKeyUsagesExtension(options.extensions?.extendedKeyUsage))\n extensions.push(createSubjectAlternativeNameExtension(options.extensions?.subjectAlternativeName))\n\n const subjectName = convertName(options.subject)\n\n // Get the JWA signature algorithm from the public key and convert to KeySignParams\n const jwaAlgorithm = options.subjectPublicKey.signatureAlgorithm\n const signingAlgorithm = jwaAlgorithmToKeySignParams(jwaAlgorithm)\n\n const csr = await x509.Pkcs10CertificateRequestGenerator.create(\n {\n keys: { publicKey, privateKey: signingKey },\n name: subjectName,\n signingAlgorithm,\n extensions: extensions.filter((e) => e !== undefined),\n },\n webCrypto\n )\n\n const csrInstance = CertificateSigningRequest.parseCertificateRequest(csr)\n if (options.subjectPublicKey.hasKeyId) csrInstance.publicJwk.keyId = options.subjectPublicKey.keyId\n return csrInstance\n }\n\n public get subject() {\n return this.certificateRequest.subject\n }\n\n public get subjectName() {\n return this.certificateRequest.subjectName.toString()\n }\n\n public async verify(webCrypto: CredoWebCrypto) {\n const isValid = await this.certificateRequest.verify(webCrypto)\n\n if (!isValid) {\n throw new X509Error(\n `Certificate Signing Request for '${this.certificateRequest.subject}' has an invalid signature`\n )\n }\n }\n\n /**\n * Get the data elements of the certificate signing request\n */\n public get data() {\n return {\n subjectName: this.certificateRequest.subjectName.toString(),\n subject: this.certificateRequest.subject,\n pem: this.certificateRequest.toString(),\n }\n }\n\n public getSubjectNameField(field: string) {\n return this.certificateRequest.subjectName.getField(field)\n }\n\n /**\n * @param format the format to export to, defaults to `pem`\n */\n public toString(format?: 'asn' | 'pem' | 'hex' | 'base64' | 'text' | 'base64url') {\n return this.certificateRequest.toString(format ?? 'pem')\n }\n\n public equal(certificateRequest: CertificateSigningRequest) {\n const parsedOther = new x509.Pkcs10CertificateRequest(certificateRequest.rawCertificateRequest)\n\n return this.certificateRequest.equal(parsedOther)\n }\n}\n"],"mappings":"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"}