File

src/crypto/key/crypto-implementation/crypto-implementation.service.ts

Index

Properties
Methods

Constructor

constructor(configService: ConfigService)
Parameters :
Name Type Optional
configService ConfigService No

Methods

getAlg
getAlg()

Return the algorithm that is used for the crypto operations like signing.

Returns : CryptoType

The configured algorithm type

getAlgs
getAlgs(credentialFormat: CredentialFormat)

Returns the supported algorithms based on the credential format.

  • For SD-JWT VC: Returns JOSE algorithm names (ES256, EdDSA)
  • For mDOC: Returns COSE algorithm identifiers (-7, -8)
Parameters :
Name Type Optional Description
credentialFormat CredentialFormat No

The credential format

Returns : unknown[]

Array of algorithm identifiers appropriate for the format

getCrypto
getCrypto(alg?: string)

Returns the crypto implementation based on the provided or configured algorithm.

Parameters :
Name Type Optional Description
alg string Yes
  • Optional algorithm type, defaults to the configured algorithm

The appropriate crypto implementation

getCryptoFromJwk
getCryptoFromJwk(jwk: JsonWebKey)

Returns the crypto implementation directly based on the JWK properties. Currently supports Ed25519 and ES256 (P-256 curve).

Parameters :
Name Type Optional Description
jwk JsonWebKey No
  • JSON Web Key

The appropriate crypto implementation

getSupportedAlgorithms
getSupportedAlgorithms()

Returns the list of supported algorithm types

Returns : CryptoType[]

Array of supported algorithm types

Properties

Private cachedDefaultAlg
Type : CryptoType | null
Default value : null
Private Readonly cryptoMap
Type : Map<CryptoType | CryptoImplementation>
Private Readonly supportedAlgorithms
Type : CryptoType[]
Default value : ["ES256", "Ed25519"]
import { Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { jwaSignatureAlgorithmToFullySpecifiedCoseAlgorithm } from "@openid4vc/oauth2";
import { ES256 } from "@sd-jwt/crypto-nodejs";
import { CredentialFormat } from "../../../issuer/configuration/credentials/entities/credential.entity";
import { CryptoImplementation } from "./crypto-implementation";
import { ED25519 } from "./ed25519";

export type CryptoType = "ES256" | "Ed25519";

/**
 * JOSE algorithm names used for SD-JWT VC
 */
export type JoseAlgorithm = "ES256" | "ES384" | "ES512" | "EdDSA";

/**
 * COSE algorithm identifiers used for mDOC (ISO 18013-5)
 * Uses RFC 9864 fully-specified algorithm identifiers
 * @see https://www.rfc-editor.org/rfc/rfc9864.html
 */
export type CoseAlgorithm = number;

@Injectable()
export class CryptoImplementationService {
    private readonly supportedAlgorithms: CryptoType[] = ["ES256", "Ed25519"];
    private readonly cryptoMap: Map<CryptoType, CryptoImplementation>;
    private cachedDefaultAlg: CryptoType | null = null;

    constructor(private readonly configService: ConfigService) {
        // Initialize the map of algorithms to implementations
        this.cryptoMap = new Map([
            ["ES256", ES256],
            ["Ed25519", ED25519],
        ]);
    }

    /**
     * Returns the list of supported algorithm types
     * @returns Array of supported algorithm types
     */
    getSupportedAlgorithms(): CryptoType[] {
        return [...this.supportedAlgorithms];
    }

    /**
     * Returns the supported algorithms based on the credential format.
     * - For SD-JWT VC: Returns JOSE algorithm names (ES256, EdDSA)
     * - For mDOC: Returns COSE algorithm identifiers (-7, -8)
     * @param credentialFormat The credential format
     * @returns Array of algorithm identifiers appropriate for the format
     */
    getAlgs(
        credentialFormat: CredentialFormat,
    ): (JoseAlgorithm | CoseAlgorithm)[] {
        // Map internal crypto types to JOSE algorithms
        const joseAlgs: JoseAlgorithm[] = this.supportedAlgorithms.map(
            (alg) => {
                switch (alg) {
                    case "ES256":
                        return "ES256";
                    case "Ed25519":
                        return "EdDSA";
                    default:
                        return "ES256";
                }
            },
        );

        if (credentialFormat === CredentialFormat.SD_JWT) {
            return joseAlgs;
        }

        if (credentialFormat === CredentialFormat.MSO_MDOC) {
            return joseAlgs
                .map((alg) =>
                    jwaSignatureAlgorithmToFullySpecifiedCoseAlgorithm(alg),
                )
                .filter((alg) => alg !== undefined);
        }

        // Default to JOSE algorithms
        return joseAlgs;
    }

    /**
     * Return the algorithm that is used for the crypto operations like signing.
     * @returns The configured algorithm type
     */
    getAlg(): CryptoType {
        if (!this.cachedDefaultAlg) {
            this.cachedDefaultAlg = this.configService.get(
                "CRYPTO_ALG",
            ) as CryptoType;

            // Validate the algorithm type
            if (!this.supportedAlgorithms.includes(this.cachedDefaultAlg)) {
                throw new Error(
                    `Unsupported algorithm: ${this.cachedDefaultAlg}`,
                );
            }
        }

        return this.cachedDefaultAlg;
    }

    /**
     * Returns the crypto implementation directly based on the JWK properties.
     * Currently supports Ed25519 and ES256 (P-256 curve).
     * @param jwk - JSON Web Key
     * @returns The appropriate crypto implementation
     * @throws Error if the crypto implementation cannot be determined from the JWK
     */
    getCryptoFromJwk(jwk: JsonWebKey): CryptoImplementation {
        if (!jwk || typeof jwk !== "object") {
            throw new Error("Invalid JWK provided");
        }

        // Check for Ed25519 curve
        if (jwk.crv === "Ed25519") {
            return this.cryptoMap.get("Ed25519")!;
        }

        // Check for ES256 (P-256 curve)
        if (jwk.kty === "EC" && jwk.crv === "P-256") {
            return this.cryptoMap.get("ES256")!;
        }

        throw new Error(
            `Unable to determine crypto implementation from JWK: unsupported key type or curve`,
        );
    }

    /**
     * Returns the crypto implementation based on the provided or configured algorithm.
     * @param alg - Optional algorithm type, defaults to the configured algorithm
     * @returns The appropriate crypto implementation
     * @throws Error if the algorithm is not supported
     */
    getCrypto(alg?: string): CryptoImplementation {
        const algorithmType = alg || this.getAlg();
        const implementation = this.cryptoMap.get(algorithmType as CryptoType);

        if (!implementation) {
            throw new Error(`Unsupported algorithm: ${algorithmType}`);
        }

        return implementation;
    }
}

results matching ""

    No results matching ""