@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
148 lines (144 loc) • 6.62 kB
JavaScript
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 { createExtendedKeyUsagesExtension, createKeyUsagesExtension, createSubjectAlternativeNameExtension, createSubjectKeyIdentifierExtension } from "./utils/extensions.mjs";
import { X509Error } from "./X509Error.mjs";
import { convertName } from "./utils/nameConversion.mjs";
import "./utils/index.mjs";
import { X509KeyUsage } from "./X509Certificate.mjs";
import { AsnParser } from "@peculiar/asn1-schema";
import { SubjectPublicKeyInfo, id_ce_extKeyUsage, id_ce_keyUsage, id_ce_subjectAltName, id_ce_subjectKeyIdentifier } 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) {
return new CertificateSigningRequest({
publicJwk: spkiToPublicJwk(AsnParser.parse(certificateRequest.publicKey.rawData, SubjectPublicKeyInfo)),
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(id_ce_subjectAltName)?.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(id_ce_subjectKeyIdentifier)?.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(id_ce_keyUsage)?.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(id_ce_extKeyUsage)?.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