Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/node_modules
/.idea
/lib
/tmp
/coverage
.DS_Store
13 changes: 7 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 12 additions & 6 deletions src/mdoc/model/Document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,24 +163,30 @@ export class Document {
*
* @param {Object} params - The parameters object
* @param {jose.JWK | Uint8Array} params.issuerPrivateKey - The issuer's private key either in JWK format or COSE_KEY format as buffer.
* @param {string | Uint8Array} params.issuerCertificate - The issuer's certificate in pem format or as a buffer.
* @param {string | Uint8Array | Array<string | Uint8Array>} params.issuerCertificate - The issuer's certificate in pem format, as a buffer, or an array.
* @param {SupportedAlgs} params.alg - The algorhitm used for the MSO signature.
* @param {string | Uint8Array} [params.kid] - The key id of the issuer's private key. default: issuerPrivateKey.kid
* @returns {Promise<IssuerSignedDoc>} - The signed document
*/
async sign(params: {
issuerPrivateKey: jose.JWK | Uint8Array,
issuerCertificate: string | Uint8Array,
issuerCertificate: string | Uint8Array | Array<string | Uint8Array>,
alg: SupportedAlgs,
kid?: string | Uint8Array,
}): Promise<IssuerSignedDocument> {
if (!this.#issuerNameSpaces) {
throw new Error('No namespaces added');
}

const issuerPublicKeyBuffer = typeof params.issuerCertificate === 'string' ?
fromPEM(params.issuerCertificate) :
params.issuerCertificate;
let issuerCertificateChain: Uint8Array[];

if (Array.isArray(params.issuerCertificate)) {
issuerCertificateChain = params.issuerCertificate.flatMap((cert) => (typeof cert === 'string' ? fromPEM(cert) : [cert]));
} else if (typeof params.issuerCertificate === 'string') {
issuerCertificateChain = fromPEM(params.issuerCertificate);
} else {
issuerCertificateChain = [params.issuerCertificate];
}

const issuerPrivateKeyJWK = params.issuerPrivateKey instanceof Uint8Array ?
COSEKeyToJWK(params.issuerPrivateKey) :
Expand Down Expand Up @@ -210,7 +216,7 @@ export class Document {
const protectedHeader: ProtectedHeaders = { alg: params.alg };
const unprotectedHeader: UnprotectedHeaders = {
kid: params.kid ?? issuerPrivateKeyJWK.kid,
x5chain: [issuerPublicKeyBuffer],
x5chain: issuerCertificateChain.length === 1 ? issuerCertificateChain[0] : issuerCertificateChain,
};

const issuerAuth = await IssuerAuth.sign(
Expand Down
18 changes: 15 additions & 3 deletions src/mdoc/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,19 @@ export function getRandomBytes(len: number) {
return webcrypto.getRandomValues(new Uint8Array(len));
}

export function fromPEM(pem: string): Uint8Array {
const base64 = pem.replace(/-{5}(BEGIN|END) .*-{5}/gm, '').replace(/\s/gm, '');
return Buffer.from(base64, 'base64');
export function fromPEM(pem: string): Uint8Array[] {
const certs = pem
.split(/-----END CERTIFICATE-----/)
.map((block) => block.trim())
.filter((block) => block.length > 0)
.map((block) => {
const fullBlock = `${block}\n-----END CERTIFICATE-----`;
const base64 = fullBlock
.replace(/-----BEGIN CERTIFICATE-----/, '')
.replace(/-----END CERTIFICATE-----/, '')
.replace(/\s+/g, '');
return Buffer.from(base64, 'base64');
});

return certs;
}
Binary file removed tmp/device-response.mdl
Binary file not shown.
1 change: 0 additions & 1 deletion tmp/ephemeral-reader-key

This file was deleted.

Binary file removed tmp/session-transcript
Binary file not shown.