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

147 lines (146 loc) • 6.54 kB
import "../kms/index.mjs"; import { CredoWebCryptoKey } from "../../crypto/webcrypto/CredoWebCryptoKey.mjs"; import { jwaAlgorithmToKeySignParams } from "../../crypto/webcrypto/types.mjs"; import { publicJwkToCryptoKeyAlgorithm, spkiToPublicJwk } from "../../crypto/webcrypto/utils/keyAlgorithmConversion.mjs"; import "../../crypto/webcrypto/utils/index.mjs"; import "../../crypto/webcrypto/index.mjs"; import { X509Error } from "./X509Error.mjs"; import { convertName } from "./utils/nameConversion.mjs"; import { createExtendedKeyUsagesExtension, createKeyUsagesExtension, createSubjectAlternativeNameExtension, createSubjectKeyIdentifierExtension } from "./utils/extensions.mjs"; import "./utils/index.mjs"; import { X509KeyUsage } from "./X509Certificate.mjs"; import { AsnParser } from "@peculiar/asn1-schema"; import { SubjectPublicKeyInfo } from "@peculiar/asn1-x509"; import * as x509 from "@peculiar/x509"; //#region src/modules/x509/CertificateSigningRequest.ts var CertificateSigningRequest = class CertificateSigningRequest { constructor(options) { this.publicJwk = options.publicJwk; this.certificateRequest = options.certificateRequest; } set keyId(keyId) { this.publicJwk.keyId = keyId; } get keyId() { return this.publicJwk.keyId; } get hasKeyId() { return this.publicJwk.hasKeyId; } static fromRawCertificateRequest(rawCertificateRequest) { const certificateRequest = new x509.Pkcs10CertificateRequest(rawCertificateRequest); return CertificateSigningRequest.parseCertificateRequest(certificateRequest); } static fromEncodedCertificateRequest(encodedCertificateRequest) { const certificateRequest = new x509.Pkcs10CertificateRequest(encodedCertificateRequest); return CertificateSigningRequest.parseCertificateRequest(certificateRequest); } static parseCertificateRequest(certificateRequest) { const spki = AsnParser.parse(certificateRequest.publicKey.rawData, SubjectPublicKeyInfo); const publicJwk = spkiToPublicJwk(spki); return new CertificateSigningRequest({ publicJwk, certificateRequest }); } getMatchingExtensions(objectIdentifier) { const matchingExtensions = this.certificateRequest.extensions.filter((e) => e.type === objectIdentifier); if (matchingExtensions.length === 0) return void 0; return matchingExtensions; } get rawCertificateRequest() { return new Uint8Array(this.certificateRequest.rawData); } get subjectAlternativeNames() { return this.getMatchingExtensions("2.5.29.17")?.flatMap((s) => s.names.items ?? []).map((i) => ({ type: i.type, value: i.value })) ?? []; } get sanDnsNames() { return this.subjectAlternativeNames.filter((san) => san.type === "dns").map((san) => san.value); } get sanUriNames() { return this.subjectAlternativeNames.filter((san) => san.type === "url").map((san) => san.value); } get subjectKeyIdentifier() { const keyIds = this.getMatchingExtensions("2.5.29.14")?.map((e) => e.keyId); if (keyIds && keyIds.length > 1) throw new X509Error("Multiple Subject Key Identifiers are not allowed"); return keyIds?.[0]; } get keyUsage() { const keyUsages = this.getMatchingExtensions("2.5.29.15")?.map((e) => e.usages); if (keyUsages && keyUsages.length > 1) throw new X509Error("Multiple Key Usages are not allowed"); if (keyUsages && keyUsages.length > 0) return Object.values(X509KeyUsage).filter((key) => typeof key === "number").filter((flagValue) => (keyUsages[0] & flagValue) === flagValue).map((flagValue) => flagValue); return []; } get extendedKeyUsage() { const extendedKeyUsages = this.getMatchingExtensions("2.5.29.37")?.map((e) => e.usages); if (extendedKeyUsages && extendedKeyUsages.length > 1) throw new X509Error("Multiple Extended Key Usages are not allowed"); return extendedKeyUsages?.[0] ?? []; } isExtensionCritical(id) { const extension = this.getMatchingExtensions(id); if (!extension) throw new X509Error(`extension with id '${id}' is not found`); return !!extension[0].critical; } static async create(options, webCrypto) { const signingKey = new CredoWebCryptoKey(options.subjectPublicKey, publicJwkToCryptoKeyAlgorithm(options.subjectPublicKey), false, "private", ["sign"]); const publicKey = new CredoWebCryptoKey(options.subjectPublicKey, publicJwkToCryptoKeyAlgorithm(options.subjectPublicKey), true, "public", ["verify"]); const extensions = []; extensions.push(createSubjectKeyIdentifierExtension(options.extensions?.subjectKeyIdentifier, { publicJwk: options.subjectPublicKey })); extensions.push(createKeyUsagesExtension(options.extensions?.keyUsage)); extensions.push(createExtendedKeyUsagesExtension(options.extensions?.extendedKeyUsage)); extensions.push(createSubjectAlternativeNameExtension(options.extensions?.subjectAlternativeName)); const subjectName = convertName(options.subject); const jwaAlgorithm = options.subjectPublicKey.signatureAlgorithm; const signingAlgorithm = jwaAlgorithmToKeySignParams(jwaAlgorithm); const csr = await x509.Pkcs10CertificateRequestGenerator.create({ keys: { publicKey, privateKey: signingKey }, name: subjectName, signingAlgorithm, extensions: extensions.filter((e) => e !== void 0) }, webCrypto); const csrInstance = CertificateSigningRequest.parseCertificateRequest(csr); if (options.subjectPublicKey.hasKeyId) csrInstance.publicJwk.keyId = options.subjectPublicKey.keyId; return csrInstance; } get subject() { return this.certificateRequest.subject; } get subjectName() { return this.certificateRequest.subjectName.toString(); } async verify(webCrypto) { if (!await this.certificateRequest.verify(webCrypto)) throw new X509Error(`Certificate Signing Request for '${this.certificateRequest.subject}' has an invalid signature`); } /** * Get the data elements of the certificate signing request */ get data() { return { subjectName: this.certificateRequest.subjectName.toString(), subject: this.certificateRequest.subject, pem: this.certificateRequest.toString() }; } getSubjectNameField(field) { return this.certificateRequest.subjectName.getField(field); } /** * @param format the format to export to, defaults to `pem` */ toString(format) { return this.certificateRequest.toString(format ?? "pem"); } equal(certificateRequest) { const parsedOther = new x509.Pkcs10CertificateRequest(certificateRequest.rawCertificateRequest); return this.certificateRequest.equal(parsedOther); } }; //#endregion export { CertificateSigningRequest }; //# sourceMappingURL=CertificateSigningRequest.mjs.map