Skip to content

Commit

Permalink
0.0.0-alpha.14
Browse files Browse the repository at this point in the history
  • Loading branch information
tamaina committed Mar 3, 2024
1 parent b96fce6 commit ed20c0a
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 43 deletions.
63 changes: 52 additions & 11 deletions dist/index.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ __export(src_exports, {
HTTPMessageSignaturesParseError: () => HTTPMessageSignaturesParseError,
InvalidRequestError: () => InvalidRequestError,
Pkcs1ParseError: () => Pkcs1ParseError,
Pkcs8ParseError: () => Pkcs8ParseError,
RequestHasMultipleDateHeadersError: () => RequestHasMultipleDateHeadersError,
RequestHasMultipleSignatureHeadersError: () => RequestHasMultipleSignatureHeadersError,
SignatureHeaderNotFoundError: () => SignatureHeaderNotFoundError,
Expand Down Expand Up @@ -66,9 +67,11 @@ __export(src_exports, {
lcObjectKey: () => lcObjectKey,
numberToUint8Array: () => numberToUint8Array,
objectLcKeys: () => objectLcKeys,
parseAlgorithmIdentifier: () => parseAlgorithmIdentifier,
parseDraftRequest: () => parseDraftRequest,
parseDraftRequestSignatureHeader: () => parseDraftRequestSignatureHeader,
parsePkcs1: () => parsePkcs1,
parsePkcs8: () => parsePkcs8,
parsePublicKey: () => parsePublicKey,
parseRequestSignature: () => parseRequestSignature,
parseSpki: () => parseSpki,
Expand Down Expand Up @@ -798,29 +801,34 @@ function decodePem(input) {
const der = typeof input === "string" ? reHex.test(input) ? import_hex.default.decode(input) : import_base64.default.unarmor(input) : input;
return der;
}
function parseSpki(input) {
const parsed = import_asn1js2.default.decode(decodePem(input));
if (!parsed.sub || parsed.sub.length === 0 || parsed.sub.length > 2)
throw new SpkiParseError("Invalid SPKI (invalid sub)");
const algorithmIdentifierSub = parsed.sub && parsed.sub[0] && parsed.sub[0].sub;
function parseAlgorithmIdentifier(input) {
const algorithmIdentifierSub = input.sub;
if (!algorithmIdentifierSub)
throw new SpkiParseError("Invalid SPKI (no AlgorithmIdentifier)");
throw new SpkiParseError("Invalid AlgorithmIdentifier");
if (algorithmIdentifierSub.length === 0)
throw new SpkiParseError("Invalid SPKI (invalid AlgorithmIdentifier sub length, zero)");
throw new SpkiParseError("Invalid AlgorithmIdentifier (sub length, zero)");
if (algorithmIdentifierSub.length > 2)
throw new SpkiParseError("Invalid SPKI (invalid AlgorithmIdentifier sub length, too many)");
throw new SpkiParseError("Invalid AlgorithmIdentifier (sub length, too many)");
if (algorithmIdentifierSub[0].tag.tagNumber !== 6)
throw new SpkiParseError("Invalid SPKI (invalid AlgorithmIdentifier.sub[0] type)");
throw new SpkiParseError("Invalid AlgorithmIdentifier (.sub[0] type)");
const algorithm = algorithmIdentifierSub[0]?.content() ?? null;
if (typeof algorithm !== "string")
throw new SpkiParseError("Invalid SPKI (invalid algorithm content)");
throw new SpkiParseError("Invalid AlgorithmIdentifier (invalid content)");
const parameter = algorithmIdentifierSub[1]?.content() ?? null;
return {
der: asn1ToArrayBuffer(parsed),
algorithm,
parameter
};
}
function parseSpki(input) {
const parsed = import_asn1js2.default.decode(decodePem(input));
if (!parsed.sub || parsed.sub.length === 0 || parsed.sub.length > 2)
throw new SpkiParseError("Invalid SPKI (invalid sub)");
return {
der: asn1ToArrayBuffer(parsed),
...parseAlgorithmIdentifier(parsed.sub[0])
};
}
function parsePublicKey(input) {
try {
return parseSpki(input);
Expand Down Expand Up @@ -916,6 +924,36 @@ async function webVerifyDraftSignature(parsed, publicKeyPem, errorLogger) {
return false;
}
}

// src/pem/pkcs8.ts
var import_asn1js3 = __toESM(require("@lapo/asn1js"), 1);
var Pkcs8ParseError = class extends Error {
constructor(message) {
super(message);
}
};
function parsePkcs8(input) {
const parsed = import_asn1js3.default.decode(decodePem(input));
if (!parsed.sub || parsed.sub.length < 3 || parsed.sub.length > 4)
throw new Pkcs8ParseError("Invalid PKCS#8 (invalid sub length)");
const version = parsed.sub[0];
if (!version || !version.tag || version.tag.tagNumber !== 2)
throw new Pkcs8ParseError("Invalid PKCS#8 (invalid version)");
const privateKeyAlgorithm = parseAlgorithmIdentifier(parsed.sub[1]);
const privateKey = parsed.sub[2];
if (!privateKey || !privateKey.tag || privateKey.tag.tagNumber !== 4)
throw new Pkcs8ParseError("Invalid PKCS#8 (invalid privateKey)");
const attributes = parsed.sub[3];
if (attributes) {
if (attributes.tag.tagNumber !== 49)
throw new Pkcs8ParseError("Invalid PKCS#8 (invalid attributes)");
}
return {
privateKey: asn1ToArrayBuffer(privateKey),
...privateKeyAlgorithm,
attributesRaw: attributes ? asn1ToArrayBuffer(attributes) : null
};
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
ClockSkewInvalidError,
Expand All @@ -925,6 +963,7 @@ async function webVerifyDraftSignature(parsed, publicKeyPem, errorLogger) {
HTTPMessageSignaturesParseError,
InvalidRequestError,
Pkcs1ParseError,
Pkcs8ParseError,
RequestHasMultipleDateHeadersError,
RequestHasMultipleSignatureHeadersError,
SignatureHeaderNotFoundError,
Expand Down Expand Up @@ -954,9 +993,11 @@ async function webVerifyDraftSignature(parsed, publicKeyPem, errorLogger) {
lcObjectKey,
numberToUint8Array,
objectLcKeys,
parseAlgorithmIdentifier,
parseDraftRequest,
parseDraftRequestSignatureHeader,
parsePkcs1,
parsePkcs8,
parsePublicKey,
parseRequestSignature,
parseSpki,
Expand Down
1 change: 1 addition & 0 deletions dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ export * from './rfc9421/verify.js';
*/
export * from './pem/spki.js';
export * from './pem/pkcs1.js';
export * from './pem/pkcs8.js';
60 changes: 49 additions & 11 deletions dist/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -709,29 +709,34 @@ function decodePem(input) {
const der = typeof input === "string" ? reHex.test(input) ? Hex.decode(input) : Base64.unarmor(input) : input;
return der;
}
function parseSpki(input) {
const parsed = ASN12.decode(decodePem(input));
if (!parsed.sub || parsed.sub.length === 0 || parsed.sub.length > 2)
throw new SpkiParseError("Invalid SPKI (invalid sub)");
const algorithmIdentifierSub = parsed.sub && parsed.sub[0] && parsed.sub[0].sub;
function parseAlgorithmIdentifier(input) {
const algorithmIdentifierSub = input.sub;
if (!algorithmIdentifierSub)
throw new SpkiParseError("Invalid SPKI (no AlgorithmIdentifier)");
throw new SpkiParseError("Invalid AlgorithmIdentifier");
if (algorithmIdentifierSub.length === 0)
throw new SpkiParseError("Invalid SPKI (invalid AlgorithmIdentifier sub length, zero)");
throw new SpkiParseError("Invalid AlgorithmIdentifier (sub length, zero)");
if (algorithmIdentifierSub.length > 2)
throw new SpkiParseError("Invalid SPKI (invalid AlgorithmIdentifier sub length, too many)");
throw new SpkiParseError("Invalid AlgorithmIdentifier (sub length, too many)");
if (algorithmIdentifierSub[0].tag.tagNumber !== 6)
throw new SpkiParseError("Invalid SPKI (invalid AlgorithmIdentifier.sub[0] type)");
throw new SpkiParseError("Invalid AlgorithmIdentifier (.sub[0] type)");
const algorithm = algorithmIdentifierSub[0]?.content() ?? null;
if (typeof algorithm !== "string")
throw new SpkiParseError("Invalid SPKI (invalid algorithm content)");
throw new SpkiParseError("Invalid AlgorithmIdentifier (invalid content)");
const parameter = algorithmIdentifierSub[1]?.content() ?? null;
return {
der: asn1ToArrayBuffer(parsed),
algorithm,
parameter
};
}
function parseSpki(input) {
const parsed = ASN12.decode(decodePem(input));
if (!parsed.sub || parsed.sub.length === 0 || parsed.sub.length > 2)
throw new SpkiParseError("Invalid SPKI (invalid sub)");
return {
der: asn1ToArrayBuffer(parsed),
...parseAlgorithmIdentifier(parsed.sub[0])
};
}
function parsePublicKey(input) {
try {
return parseSpki(input);
Expand Down Expand Up @@ -827,6 +832,36 @@ async function webVerifyDraftSignature(parsed, publicKeyPem, errorLogger) {
return false;
}
}

// src/pem/pkcs8.ts
import ASN13 from "@lapo/asn1js";
var Pkcs8ParseError = class extends Error {
constructor(message) {
super(message);
}
};
function parsePkcs8(input) {
const parsed = ASN13.decode(decodePem(input));
if (!parsed.sub || parsed.sub.length < 3 || parsed.sub.length > 4)
throw new Pkcs8ParseError("Invalid PKCS#8 (invalid sub length)");
const version = parsed.sub[0];
if (!version || !version.tag || version.tag.tagNumber !== 2)
throw new Pkcs8ParseError("Invalid PKCS#8 (invalid version)");
const privateKeyAlgorithm = parseAlgorithmIdentifier(parsed.sub[1]);
const privateKey = parsed.sub[2];
if (!privateKey || !privateKey.tag || privateKey.tag.tagNumber !== 4)
throw new Pkcs8ParseError("Invalid PKCS#8 (invalid privateKey)");
const attributes = parsed.sub[3];
if (attributes) {
if (attributes.tag.tagNumber !== 49)
throw new Pkcs8ParseError("Invalid PKCS#8 (invalid attributes)");
}
return {
privateKey: asn1ToArrayBuffer(privateKey),
...privateKeyAlgorithm,
attributesRaw: attributes ? asn1ToArrayBuffer(attributes) : null
};
}
export {
ClockSkewInvalidError,
DraftSignatureHeaderClockInvalidError,
Expand All @@ -835,6 +870,7 @@ export {
HTTPMessageSignaturesParseError,
InvalidRequestError,
Pkcs1ParseError,
Pkcs8ParseError,
RequestHasMultipleDateHeadersError,
RequestHasMultipleSignatureHeadersError,
SignatureHeaderNotFoundError,
Expand Down Expand Up @@ -864,9 +900,11 @@ export {
lcObjectKey,
numberToUint8Array,
objectLcKeys,
parseAlgorithmIdentifier,
parseDraftRequest,
parseDraftRequestSignatureHeader,
parsePkcs1,
parsePkcs8,
parsePublicKey,
parseRequestSignature,
parseSpki,
Expand Down
3 changes: 3 additions & 0 deletions dist/pem/pkcs1.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import ASN1 from '@lapo/asn1js';
export declare class Pkcs1ParseError extends Error {
constructor(message: string);
}
/**
* Parse PKCS#1 public key
*/
export declare function parsePkcs1(input: ASN1.StreamOrBinary): {
pkcs1: ArrayBufferLike;
modulus: number;
Expand Down
42 changes: 42 additions & 0 deletions dist/pem/pkcs8.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import ASN1 from '@lapo/asn1js';
export declare class Pkcs8ParseError extends Error {
constructor(message: string);
}
/**
* Parse PKCS#8 private key
*
* PrivateKeyInfo ::= SEQUENCE {
* version Version,
* privateKeyAlgorithm AlgorithmIdentifier {{PrivateKeyAlgorithms}},
* privateKey PrivateKey,
* attributes [0] Attributes OPTIONAL }
*
* PrivateKey ::= OCTET STRING
* Version ::= INTEGER
* Attributes ::= SET OF Attribute
* @param input
* @returns
*/
export declare function parsePkcs8(input: ASN1.StreamOrBinary): {
attributesRaw: ArrayBuffer | null;
algorithm: string;
parameter: any;
privateKey: ArrayBufferLike;
} | {
attributesRaw: ArrayBuffer | null;
algorithm: "1.2.840.113549.1.1.1\nrsaEncryption\nPKCS #1";
parameter: null;
privateKey: ArrayBufferLike;
} | {
attributesRaw: ArrayBuffer | null;
der: ArrayBuffer;
algorithm: "1.3.101.112\ncurveEd25519\nEdDSA 25519 signature algorithm";
parameter: null;
privateKey: ArrayBufferLike;
} | {
attributesRaw: ArrayBuffer | null;
der: ArrayBuffer;
algorithm: "1.2.840.10045.2.1\necPublicKey\nANSI X9.62 public key type";
parameter: "1.2.840.10045.3.1.7\nprime256v1\nANSI X9.62 named elliptic curve";
privateKey: ArrayBufferLike;
};
42 changes: 22 additions & 20 deletions dist/pem/spki.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ export declare function getPublicKeyAlgorithmNameFromOid(oidStr: string): "RSASS
* (Most environments may implement only P-256, P-384 and P-521)
*/
export declare function getNistCurveFromOid(oidStr: string): "P-192" | "P-224" | "P-256" | "P-384" | "P-521";
export type SpkiParsedAlgorithmIdentifierBase = {
/**
* DER
*
* (Somehow crypto.createPublicKey will cause `error:1E08010C:DECODER routines::unsupported`)
*/
der: ArrayBuffer;
/**
* Convert ASN1(@lapo/asn1js).Binary to ArrayBuffer
*
* @param asn1 ASN1 object
* @param contentOnly If true, return content only, excluding tag and length
* @examples `asn1BinaryToArrayBuffer(ASN1.decode(der).stream.enc);`
*/
export declare function asn1ToArrayBuffer(asn1: ASN1, contentOnly?: boolean): ArrayBufferLike;
export type ParsedAlgorithmIdentifierBase = {
/**
* Parsed algorithm, 3 lines string
* Data from https://github.com/lapo-luchini/asn1js/blob/trunk/oids.js
Expand All @@ -42,31 +44,31 @@ export type SpkiParsedAlgorithmIdentifierBase = {
*/
parameter: any;
};
/**
* Convert ASN1(@lapo/asn1js).Binary to ArrayBuffer
*
* @param asn1 ASN1 object
* @param contentOnly If true, return content only, excluding tag and length
* @examples `asn1BinaryToArrayBuffer(ASN1.decode(der).stream.enc);`
*/
export declare function asn1ToArrayBuffer(asn1: ASN1, contentOnly?: boolean): ArrayBufferLike;
export type SpkiParsedRSAIdentifier = {
der: ArrayBuffer;
export type ParsedRSAIdentifier = {
algorithm: '1.2.840.113549.1.1.1\nrsaEncryption\nPKCS #1';
parameter: null;
};
export type SpkiParsedEd25519Identifier = {
export type ParsedEd25519Identifier = {
der: ArrayBuffer;
algorithm: '1.3.101.112\ncurveEd25519\nEdDSA 25519 signature algorithm';
parameter: null;
};
export type SpkiParsedNPrime256v1Identifier = {
export type ParsedNPrime256v1Identifier = {
der: ArrayBuffer;
algorithm: '1.2.840.10045.2.1\necPublicKey\nANSI X9.62 public key type';
parameter: '1.2.840.10045.3.1.7\nprime256v1\nANSI X9.62 named elliptic curve';
};
export type SpkiParsedAlgorithmIdentifier = SpkiParsedRSAIdentifier | SpkiParsedEd25519Identifier | SpkiParsedNPrime256v1Identifier | SpkiParsedAlgorithmIdentifierBase;
export type ParsedAlgorithmIdentifier = ParsedRSAIdentifier | ParsedEd25519Identifier | ParsedNPrime256v1Identifier | ParsedAlgorithmIdentifierBase;
export type SpkiParsedAlgorithmIdentifier = ParsedAlgorithmIdentifierBase & {
/**
* DER
*
* (Somehow crypto.createPublicKey will cause `error:1E08010C:DECODER routines::unsupported`)
*/
der: ArrayBuffer;
};
export declare function decodePem(input: ASN1.StreamOrBinary): Exclude<ASN1.StreamOrBinary, string>;
export declare function parseAlgorithmIdentifier(input: ASN1): ParsedAlgorithmIdentifier;
/**
* Parse X.509 SubjectPublicKeyInfo (SPKI) public key
* @param input SPKI public key PEM or DER
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@misskey-dev/node-http-message-signatures",
"version": "0.0.0-alpha.13",
"version": "0.0.0-alpha.14",
"description": "",
"type": "module",
"keywords": [
Expand Down

0 comments on commit ed20c0a

Please sign in to comment.