Use asn1 classes from webcrypto-core
This commit is contained in:
parent
d4f103e44e
commit
cf77b2e013
|
@ -68,7 +68,6 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@peculiar/asn1-schema": "^1.0.5",
|
"@peculiar/asn1-schema": "^1.0.5",
|
||||||
"@peculiar/json-schema": "^1.1.10",
|
"@peculiar/json-schema": "^1.1.10",
|
||||||
"asn1js": "^2.0.26",
|
|
||||||
"pvtsutils": "^1.0.10",
|
"pvtsutils": "^1.0.10",
|
||||||
"tslib": "^1.11.1",
|
"tslib": "^1.11.1",
|
||||||
"webcrypto-core": "^1.0.19-next.0"
|
"webcrypto-core": "^1.0.19-next.0"
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
import { AsnProp, AsnPropTypes } from "@peculiar/asn1-schema";
|
|
||||||
|
|
||||||
// RFC 5280
|
|
||||||
// https://tools.ietf.org/html/rfc5280#section-4.1.1.2
|
|
||||||
//
|
|
||||||
// AlgorithmIdentifier ::= SEQUENCE {
|
|
||||||
// algorithm OBJECT IDENTIFIER,
|
|
||||||
// parameters ANY DEFINED BY algorithm OPTIONAL }
|
|
||||||
// -- contains a value of the type
|
|
||||||
// -- registered for use with the
|
|
||||||
// -- algorithm object identifier value
|
|
||||||
|
|
||||||
export type ParametersType = ArrayBuffer | null;
|
|
||||||
|
|
||||||
export class AlgorithmIdentifier {
|
|
||||||
|
|
||||||
@AsnProp({
|
|
||||||
type: AsnPropTypes.ObjectIdentifier,
|
|
||||||
})
|
|
||||||
public algorithm!: string;
|
|
||||||
|
|
||||||
@AsnProp({
|
|
||||||
type: AsnPropTypes.Any,
|
|
||||||
optional: true,
|
|
||||||
})
|
|
||||||
public parameters?: ParametersType;
|
|
||||||
|
|
||||||
constructor(params?: Partial<AlgorithmIdentifier>) {
|
|
||||||
Object.assign(this, params);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
import { AsnIntegerConverter, AsnProp, AsnPropTypes, AsnSerializer } from "@peculiar/asn1-schema";
|
|
||||||
import { IJsonConvertible } from "@peculiar/json-schema";
|
|
||||||
import { Convert } from "pvtsutils";
|
|
||||||
import { EcPublicKey } from "./ec_public_key";
|
|
||||||
|
|
||||||
// RFC 5915
|
|
||||||
// https://tools.ietf.org/html/rfc5915#section-3
|
|
||||||
//
|
|
||||||
// ECPrivateKey ::= SEQUENCE {
|
|
||||||
// version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
|
|
||||||
// privateKey OCTET STRING,
|
|
||||||
// parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
|
|
||||||
// publicKey [1] BIT STRING OPTIONAL
|
|
||||||
// }
|
|
||||||
|
|
||||||
export class EcPrivateKey implements IJsonConvertible {
|
|
||||||
|
|
||||||
@AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerConverter })
|
|
||||||
public version = 1;
|
|
||||||
|
|
||||||
@AsnProp({ type: AsnPropTypes.OctetString })
|
|
||||||
public privateKey = new ArrayBuffer(0);
|
|
||||||
|
|
||||||
@AsnProp({ context: 0, type: AsnPropTypes.Any, optional: true })
|
|
||||||
public parameters?: ArrayBuffer;
|
|
||||||
|
|
||||||
@AsnProp({ context: 1, type: AsnPropTypes.BitString, optional: true })
|
|
||||||
public publicKey?: ArrayBuffer;
|
|
||||||
|
|
||||||
public fromJSON(json: any): this {
|
|
||||||
if (!("d" in json)) {
|
|
||||||
throw new Error("d: Missing required property");
|
|
||||||
}
|
|
||||||
this.privateKey = Convert.FromBase64Url(json.d);
|
|
||||||
|
|
||||||
if ("x" in json) {
|
|
||||||
const publicKey = new EcPublicKey();
|
|
||||||
publicKey.fromJSON(json);
|
|
||||||
|
|
||||||
this.publicKey = AsnSerializer.toASN(publicKey).valueBlock.valueHex;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
public toJSON() {
|
|
||||||
const jwk: JsonWebKey = {};
|
|
||||||
jwk.d = Convert.ToBase64Url(this.privateKey);
|
|
||||||
if (this.publicKey) {
|
|
||||||
Object.assign(jwk, new EcPublicKey(this.publicKey).toJSON());
|
|
||||||
}
|
|
||||||
return jwk;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
import { AsnProp, AsnPropTypes, AsnType, AsnTypeTypes } from "@peculiar/asn1-schema";
|
|
||||||
import { IJsonConvertible } from "@peculiar/json-schema";
|
|
||||||
import { Convert } from "pvtsutils";
|
|
||||||
import * as core from "webcrypto-core";
|
|
||||||
|
|
||||||
// RFC 5480
|
|
||||||
// https://tools.ietf.org/html/rfc5480#section-2.2
|
|
||||||
//
|
|
||||||
// ECPoint ::= OCTET STRING
|
|
||||||
|
|
||||||
@AsnType({ type: AsnTypeTypes.Choice })
|
|
||||||
export class EcPublicKey implements IJsonConvertible {
|
|
||||||
|
|
||||||
@AsnProp({ type: AsnPropTypes.OctetString })
|
|
||||||
public value = new ArrayBuffer(0);
|
|
||||||
|
|
||||||
constructor(value?: ArrayBuffer) {
|
|
||||||
if (value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public toJSON() {
|
|
||||||
let bytes = new Uint8Array(this.value);
|
|
||||||
|
|
||||||
if (bytes[0] !== 0x04) {
|
|
||||||
throw new core.CryptoError("Wrong ECPoint. Current version supports only Uncompressed (0x04) point");
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes = new Uint8Array(this.value.slice(1));
|
|
||||||
const size = bytes.length / 2;
|
|
||||||
|
|
||||||
const offset = 0;
|
|
||||||
const json = {
|
|
||||||
x: Convert.ToBase64Url(bytes.buffer.slice(offset, offset + size)),
|
|
||||||
y: Convert.ToBase64Url(bytes.buffer.slice(offset + size, offset + size + size)),
|
|
||||||
};
|
|
||||||
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
public fromJSON(json: any): this {
|
|
||||||
if (!("x" in json)) {
|
|
||||||
throw new Error("x: Missing required property");
|
|
||||||
}
|
|
||||||
if (!("y" in json)) {
|
|
||||||
throw new Error("y: Missing required property");
|
|
||||||
}
|
|
||||||
|
|
||||||
const x = Convert.FromBase64Url(json.x);
|
|
||||||
const y = Convert.FromBase64Url(json.y);
|
|
||||||
|
|
||||||
const value = Buffer.concat([
|
|
||||||
new Uint8Array([0x04]), // uncompressed bit
|
|
||||||
new Uint8Array(x),
|
|
||||||
new Uint8Array(y),
|
|
||||||
]);
|
|
||||||
|
|
||||||
this.value = new Uint8Array(value).buffer;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
import { AsnProp, AsnPropTypes, IAsnConverter } from "@peculiar/asn1-schema";
|
|
||||||
// @ts-ignore
|
|
||||||
import * as asn1 from "asn1js";
|
|
||||||
|
|
||||||
// RFC 3279
|
|
||||||
// https://tools.ietf.org/html/rfc3279#section-2.2.3
|
|
||||||
//
|
|
||||||
// ECDSA-Sig-Value ::= SEQUENCE {
|
|
||||||
// r INTEGER,
|
|
||||||
// s INTEGER
|
|
||||||
// }
|
|
||||||
|
|
||||||
export const AsnIntegerWithoutPaddingConverter: IAsnConverter<ArrayBuffer> = {
|
|
||||||
fromASN: (value: any) => {
|
|
||||||
const bytes = new Uint8Array(value.valueBlock.valueHex);
|
|
||||||
return (bytes[0] === 0)
|
|
||||||
? bytes.buffer.slice(1)
|
|
||||||
: bytes.buffer;
|
|
||||||
},
|
|
||||||
toASN: (value: ArrayBuffer) => {
|
|
||||||
const bytes = new Uint8Array(value);
|
|
||||||
if (bytes[0] > 127) {
|
|
||||||
const newValue = new Uint8Array(bytes.length + 1);
|
|
||||||
newValue.set(bytes, 1);
|
|
||||||
return new asn1.Integer({ valueHex: newValue });
|
|
||||||
}
|
|
||||||
return new asn1.Integer({ valueHex: value });
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export class EcDsaSignature {
|
|
||||||
|
|
||||||
@AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerWithoutPaddingConverter })
|
|
||||||
public r = new ArrayBuffer(0);
|
|
||||||
|
|
||||||
@AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerWithoutPaddingConverter })
|
|
||||||
public s = new ArrayBuffer(0);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
export * from "./object_identifier";
|
|
||||||
export * from "./algorithm_identifier";
|
|
||||||
export * from "./private_key_info";
|
|
||||||
export * from "./public_key_info";
|
|
||||||
export * from "./rsa_private_key";
|
|
||||||
export * from "./rsa_public_key";
|
|
||||||
export * from "./ec_private_key";
|
|
||||||
export * from "./ec_public_key";
|
|
||||||
export * from "./ec_signature";
|
|
|
@ -1,14 +0,0 @@
|
||||||
import { AsnProp, AsnPropTypes, AsnType, AsnTypeTypes } from "@peculiar/asn1-schema";
|
|
||||||
|
|
||||||
@AsnType({ type: AsnTypeTypes.Choice })
|
|
||||||
export class ObjectIdentifier {
|
|
||||||
|
|
||||||
@AsnProp({type: AsnPropTypes.ObjectIdentifier})
|
|
||||||
public value!: string;
|
|
||||||
|
|
||||||
constructor(value?: string) {
|
|
||||||
if (value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
import { AsnProp, AsnPropTypes } from "@peculiar/asn1-schema";
|
|
||||||
import { AlgorithmIdentifier } from "./algorithm_identifier";
|
|
||||||
|
|
||||||
// RFC 5208
|
|
||||||
// https://tools.ietf.org/html/rfc5208#section-5
|
|
||||||
//
|
|
||||||
// PrivateKeyInfo ::= SEQUENCE {
|
|
||||||
// version Version,
|
|
||||||
// privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
|
|
||||||
// privateKey PrivateKey,
|
|
||||||
// attributes [0] IMPLICIT Attributes OPTIONAL }
|
|
||||||
//
|
|
||||||
// Version ::= INTEGER
|
|
||||||
//
|
|
||||||
// PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
|
|
||||||
//
|
|
||||||
// PrivateKey ::= OCTET STRING
|
|
||||||
//
|
|
||||||
// Attributes ::= SET OF Attribute
|
|
||||||
|
|
||||||
export class PrivateKeyInfo {
|
|
||||||
|
|
||||||
@AsnProp({ type: AsnPropTypes.Integer })
|
|
||||||
public version = 0;
|
|
||||||
|
|
||||||
@AsnProp({ type: AlgorithmIdentifier })
|
|
||||||
public privateKeyAlgorithm = new AlgorithmIdentifier();
|
|
||||||
|
|
||||||
@AsnProp({ type: AsnPropTypes.OctetString })
|
|
||||||
public privateKey = new ArrayBuffer(0);
|
|
||||||
|
|
||||||
@AsnProp({ type: AsnPropTypes.Any, optional: true })
|
|
||||||
public attributes?: ArrayBuffer;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
import { AsnProp, AsnPropTypes } from "@peculiar/asn1-schema";
|
|
||||||
import { AlgorithmIdentifier } from "./algorithm_identifier";
|
|
||||||
|
|
||||||
// RFC 5280
|
|
||||||
// https://tools.ietf.org/html/rfc5280#section-4.1
|
|
||||||
//
|
|
||||||
// SubjectPublicKeyInfo ::= SEQUENCE {
|
|
||||||
// algorithm AlgorithmIdentifier,
|
|
||||||
// subjectPublicKey BIT STRING
|
|
||||||
|
|
||||||
export class PublicKeyInfo {
|
|
||||||
|
|
||||||
@AsnProp({ type: AlgorithmIdentifier })
|
|
||||||
public publicKeyAlgorithm = new AlgorithmIdentifier();
|
|
||||||
|
|
||||||
@AsnProp({ type: AsnPropTypes.BitString })
|
|
||||||
public publicKey = new ArrayBuffer(0);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
import { AsnIntegerConverter, AsnProp, AsnPropTypes } from "@peculiar/asn1-schema";
|
|
||||||
import { JsonProp } from "@peculiar/json-schema";
|
|
||||||
import { AsnIntegerArrayBufferConverter, JsonBase64UrlArrayBufferConverter } from "../converters";
|
|
||||||
|
|
||||||
// RFC 3437
|
|
||||||
// https://tools.ietf.org/html/rfc3447#appendix-A.1.2
|
|
||||||
//
|
|
||||||
// RSAPrivateKey ::= SEQUENCE {
|
|
||||||
// version Version,
|
|
||||||
// modulus INTEGER, -- n
|
|
||||||
// publicExponent INTEGER, -- e
|
|
||||||
// privateExponent INTEGER, -- d
|
|
||||||
// prime1 INTEGER, -- p
|
|
||||||
// prime2 INTEGER, -- q
|
|
||||||
// exponent1 INTEGER, -- d mod (p-1)
|
|
||||||
// exponent2 INTEGER, -- d mod (q-1)
|
|
||||||
// coefficient INTEGER, -- (inverse of q) mod p
|
|
||||||
// otherPrimeInfos OtherPrimeInfos OPTIONAL
|
|
||||||
// }
|
|
||||||
|
|
||||||
export class RsaPrivateKey {
|
|
||||||
|
|
||||||
@AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerConverter })
|
|
||||||
public version = 0;
|
|
||||||
|
|
||||||
@AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter })
|
|
||||||
@JsonProp({ name: "n", converter: JsonBase64UrlArrayBufferConverter })
|
|
||||||
public modulus = new ArrayBuffer(0);
|
|
||||||
|
|
||||||
@AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter })
|
|
||||||
@JsonProp({ name: "e", converter: JsonBase64UrlArrayBufferConverter })
|
|
||||||
public publicExponent = new ArrayBuffer(0);
|
|
||||||
|
|
||||||
@AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter })
|
|
||||||
@JsonProp({ name: "d", converter: JsonBase64UrlArrayBufferConverter })
|
|
||||||
public privateExponent = new ArrayBuffer(0);
|
|
||||||
|
|
||||||
@AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter })
|
|
||||||
@JsonProp({ name: "p", converter: JsonBase64UrlArrayBufferConverter })
|
|
||||||
public prime1 = new ArrayBuffer(0);
|
|
||||||
|
|
||||||
@AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter })
|
|
||||||
@JsonProp({ name: "q", converter: JsonBase64UrlArrayBufferConverter })
|
|
||||||
public prime2 = new ArrayBuffer(0);
|
|
||||||
|
|
||||||
@AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter })
|
|
||||||
@JsonProp({ name: "dp", converter: JsonBase64UrlArrayBufferConverter })
|
|
||||||
public exponent1 = new ArrayBuffer(0);
|
|
||||||
|
|
||||||
@AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter })
|
|
||||||
@JsonProp({ name: "dq", converter: JsonBase64UrlArrayBufferConverter })
|
|
||||||
public exponent2 = new ArrayBuffer(0);
|
|
||||||
|
|
||||||
@AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter })
|
|
||||||
@JsonProp({ name: "qi", converter: JsonBase64UrlArrayBufferConverter })
|
|
||||||
public coefficient = new ArrayBuffer(0);
|
|
||||||
|
|
||||||
@AsnProp({ type: AsnPropTypes.Any, optional: true })
|
|
||||||
public otherPrimeInfos?: ArrayBuffer;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { AsnProp, AsnPropTypes } from "@peculiar/asn1-schema";
|
|
||||||
import { JsonProp } from "@peculiar/json-schema";
|
|
||||||
import { AsnIntegerArrayBufferConverter, JsonBase64UrlArrayBufferConverter } from "../converters";
|
|
||||||
|
|
||||||
// RFC 3437
|
|
||||||
// https://tools.ietf.org/html/rfc3447#appendix-A.1.1
|
|
||||||
//
|
|
||||||
// RSAPublicKey ::= SEQUENCE {
|
|
||||||
// modulus INTEGER, -- n
|
|
||||||
// publicExponent INTEGER, -- e
|
|
||||||
// }
|
|
||||||
|
|
||||||
export class RsaPublicKey {
|
|
||||||
|
|
||||||
@AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter })
|
|
||||||
@JsonProp({ name: "n", converter: JsonBase64UrlArrayBufferConverter })
|
|
||||||
public modulus = new ArrayBuffer(0);
|
|
||||||
|
|
||||||
@AsnProp({ type: AsnPropTypes.Integer, converter: AsnIntegerArrayBufferConverter })
|
|
||||||
@JsonProp({ name: "e", converter: JsonBase64UrlArrayBufferConverter })
|
|
||||||
public publicExponent = new ArrayBuffer(0);
|
|
||||||
|
|
||||||
}
|
|
|
@ -5,8 +5,3 @@ export const JsonBase64UrlConverter: IJsonConverter<Buffer, string> = {
|
||||||
fromJSON: (value: string) => Buffer.from(Convert.FromBase64Url(value)),
|
fromJSON: (value: string) => Buffer.from(Convert.FromBase64Url(value)),
|
||||||
toJSON: (value: Buffer) => Convert.ToBase64Url(value),
|
toJSON: (value: Buffer) => Convert.ToBase64Url(value),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const JsonBase64UrlArrayBufferConverter: IJsonConverter<ArrayBuffer, string> = {
|
|
||||||
fromJSON: (value: string) => Convert.FromBase64Url(value),
|
|
||||||
toJSON: (value: ArrayBuffer) => Convert.ToBase64Url(new Uint8Array(value)),
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,2 +1 @@
|
||||||
export * from "./base64_url";
|
export * from "./base64_url";
|
||||||
export * from "./integer_converter";
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
import { IAsnConverter } from "@peculiar/asn1-schema";
|
|
||||||
// @ts-ignore
|
|
||||||
import * as asn1 from "asn1js";
|
|
||||||
|
|
||||||
export const AsnIntegerArrayBufferConverter: IAsnConverter<ArrayBuffer> = {
|
|
||||||
fromASN: (value: any) => {
|
|
||||||
const valueHex = value.valueBlock.valueHex;
|
|
||||||
return !(new Uint8Array(valueHex)[0])
|
|
||||||
? value.valueBlock.valueHex.slice(1)
|
|
||||||
: value.valueBlock.valueHex;
|
|
||||||
},
|
|
||||||
toASN: (value: ArrayBuffer) => {
|
|
||||||
const valueHex = new Uint8Array(value)[0] > 127
|
|
||||||
? Buffer.concat([Buffer.from([0]), Buffer.from(value)])
|
|
||||||
: Buffer.from(value);
|
|
||||||
return new asn1.Integer({ valueHex: new Uint8Array(valueHex).buffer });
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -2,8 +2,6 @@ import crypto from "crypto";
|
||||||
import { AsnParser, AsnSerializer } from "@peculiar/asn1-schema";
|
import { AsnParser, AsnSerializer } from "@peculiar/asn1-schema";
|
||||||
import { JsonParser, JsonSerializer } from "@peculiar/json-schema";
|
import { JsonParser, JsonSerializer } from "@peculiar/json-schema";
|
||||||
import * as core from "webcrypto-core";
|
import * as core from "webcrypto-core";
|
||||||
import * as asn from "../../asn";
|
|
||||||
import { ObjectIdentifier } from "../../asn";
|
|
||||||
import { CryptoKey } from "../../keys";
|
import { CryptoKey } from "../../keys";
|
||||||
import { getOidByNamedCurve } from "./helper";
|
import { getOidByNamedCurve } from "./helper";
|
||||||
import { EcPrivateKey } from "./private_key";
|
import { EcPrivateKey } from "./private_key";
|
||||||
|
@ -63,7 +61,7 @@ export class EcCrypto {
|
||||||
};
|
};
|
||||||
|
|
||||||
const signature = signer.sign(options);
|
const signature = signer.sign(options);
|
||||||
const ecSignature = AsnParser.parse(signature, asn.EcDsaSignature);
|
const ecSignature = AsnParser.parse(signature, core.asn1.EcDsaSignature);
|
||||||
|
|
||||||
const pointSize = this.getPointSize(key.algorithm.namedCurve);
|
const pointSize = this.getPointSize(key.algorithm.namedCurve);
|
||||||
const r = this.addPadding(pointSize, Buffer.from(ecSignature.r));
|
const r = this.addPadding(pointSize, Buffer.from(ecSignature.r));
|
||||||
|
@ -85,7 +83,7 @@ export class EcCrypto {
|
||||||
key: key.pem,
|
key: key.pem,
|
||||||
};
|
};
|
||||||
|
|
||||||
const ecSignature = new asn.EcDsaSignature();
|
const ecSignature = new core.asn1.EcDsaSignature();
|
||||||
const pointSize = this.getPointSize(key.algorithm.namedCurve);
|
const pointSize = this.getPointSize(key.algorithm.namedCurve);
|
||||||
ecSignature.r = this.removePadding(signature.slice(0, pointSize));
|
ecSignature.r = this.removePadding(signature.slice(0, pointSize));
|
||||||
ecSignature.s = this.removePadding(signature.slice(pointSize, pointSize + pointSize));
|
ecSignature.s = this.removePadding(signature.slice(pointSize, pointSize + pointSize));
|
||||||
|
@ -99,11 +97,11 @@ export class EcCrypto {
|
||||||
const cryptoAlg = this.getOpenSSLNamedCurve((baseKey.algorithm as EcKeyAlgorithm).namedCurve);
|
const cryptoAlg = this.getOpenSSLNamedCurve((baseKey.algorithm as EcKeyAlgorithm).namedCurve);
|
||||||
|
|
||||||
const ecdh = crypto.createECDH(cryptoAlg);
|
const ecdh = crypto.createECDH(cryptoAlg);
|
||||||
const asnPrivateKey = AsnParser.parse(baseKey.data, asn.PrivateKeyInfo);
|
const asnPrivateKey = AsnParser.parse(baseKey.data, core.asn1.PrivateKeyInfo);
|
||||||
const asnEcPrivateKey = AsnParser.parse(asnPrivateKey.privateKey, asn.EcPrivateKey);
|
const asnEcPrivateKey = AsnParser.parse(asnPrivateKey.privateKey, core.asn1.EcPrivateKey);
|
||||||
ecdh.setPrivateKey(Buffer.from(asnEcPrivateKey.privateKey));
|
ecdh.setPrivateKey(Buffer.from(asnEcPrivateKey.privateKey));
|
||||||
|
|
||||||
const asnPublicKey = AsnParser.parse((algorithm.public as CryptoKey).data, asn.PublicKeyInfo);
|
const asnPublicKey = AsnParser.parse((algorithm.public as CryptoKey).data, core.asn1.PublicKeyInfo);
|
||||||
const bits = ecdh.computeSecret(Buffer.from(asnPublicKey.publicKey));
|
const bits = ecdh.computeSecret(Buffer.from(asnPublicKey.publicKey));
|
||||||
|
|
||||||
return new Uint8Array(bits).buffer.slice(0, length >> 3);
|
return new Uint8Array(bits).buffer.slice(0, length >> 3);
|
||||||
|
@ -117,7 +115,7 @@ export class EcCrypto {
|
||||||
case "spki":
|
case "spki":
|
||||||
return new Uint8Array(key.data).buffer;
|
return new Uint8Array(key.data).buffer;
|
||||||
case "raw": {
|
case "raw": {
|
||||||
const publicKeyInfo = AsnParser.parse(key.data, asn.PublicKeyInfo);
|
const publicKeyInfo = AsnParser.parse(key.data, core.asn1.PublicKeyInfo);
|
||||||
return publicKeyInfo.publicKey;
|
return publicKeyInfo.publicKey;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -130,25 +128,25 @@ export class EcCrypto {
|
||||||
case "jwk": {
|
case "jwk": {
|
||||||
const jwk = keyData as JsonWebKey;
|
const jwk = keyData as JsonWebKey;
|
||||||
if (jwk.d) {
|
if (jwk.d) {
|
||||||
const asnKey = JsonParser.fromJSON(keyData, { targetSchema: asn.EcPrivateKey });
|
const asnKey = JsonParser.fromJSON(keyData, { targetSchema: core.asn1.EcPrivateKey });
|
||||||
return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages);
|
return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages);
|
||||||
} else {
|
} else {
|
||||||
const asnKey = JsonParser.fromJSON(keyData, { targetSchema: asn.EcPublicKey });
|
const asnKey = JsonParser.fromJSON(keyData, { targetSchema: core.asn1.EcPublicKey });
|
||||||
return this.importPublicKey(asnKey, algorithm, extractable, keyUsages);
|
return this.importPublicKey(asnKey, algorithm, extractable, keyUsages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "raw": {
|
case "raw": {
|
||||||
const asnKey = new asn.EcPublicKey(keyData as ArrayBuffer);
|
const asnKey = new core.asn1.EcPublicKey(keyData as ArrayBuffer);
|
||||||
return this.importPublicKey(asnKey, algorithm, extractable, keyUsages);
|
return this.importPublicKey(asnKey, algorithm, extractable, keyUsages);
|
||||||
}
|
}
|
||||||
case "spki": {
|
case "spki": {
|
||||||
const keyInfo = AsnParser.parse(new Uint8Array(keyData as ArrayBuffer), asn.PublicKeyInfo);
|
const keyInfo = AsnParser.parse(new Uint8Array(keyData as ArrayBuffer), core.asn1.PublicKeyInfo);
|
||||||
const asnKey = new asn.EcPublicKey(keyInfo.publicKey);
|
const asnKey = new core.asn1.EcPublicKey(keyInfo.publicKey);
|
||||||
return this.importPublicKey(asnKey, algorithm, extractable, keyUsages);
|
return this.importPublicKey(asnKey, algorithm, extractable, keyUsages);
|
||||||
}
|
}
|
||||||
case "pkcs8": {
|
case "pkcs8": {
|
||||||
const keyInfo = AsnParser.parse(new Uint8Array(keyData as ArrayBuffer), asn.PrivateKeyInfo);
|
const keyInfo = AsnParser.parse(new Uint8Array(keyData as ArrayBuffer), core.asn1.PrivateKeyInfo);
|
||||||
const asnKey = AsnParser.parse(keyInfo.privateKey, asn.EcPrivateKey);
|
const asnKey = AsnParser.parse(keyInfo.privateKey, core.asn1.EcPrivateKey);
|
||||||
return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages);
|
return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -156,10 +154,10 @@ export class EcCrypto {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static async importPrivateKey(asnKey: asn.EcPrivateKey, algorithm: EcKeyImportParams, extractable: boolean, keyUsages: KeyUsage[]) {
|
protected static async importPrivateKey(asnKey: core.asn1.EcPrivateKey, algorithm: EcKeyImportParams, extractable: boolean, keyUsages: KeyUsage[]) {
|
||||||
const keyInfo = new asn.PrivateKeyInfo();
|
const keyInfo = new core.asn1.PrivateKeyInfo();
|
||||||
keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.10045.2.1";
|
keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.10045.2.1";
|
||||||
keyInfo.privateKeyAlgorithm.parameters = AsnSerializer.serialize(new ObjectIdentifier(getOidByNamedCurve(algorithm.namedCurve)));
|
keyInfo.privateKeyAlgorithm.parameters = AsnSerializer.serialize(new core.asn1.ObjectIdentifier(getOidByNamedCurve(algorithm.namedCurve)));
|
||||||
keyInfo.privateKey = AsnSerializer.serialize(asnKey);
|
keyInfo.privateKey = AsnSerializer.serialize(asnKey);
|
||||||
|
|
||||||
const key = new EcPrivateKey();
|
const key = new EcPrivateKey();
|
||||||
|
@ -172,10 +170,10 @@ export class EcCrypto {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static async importPublicKey(asnKey: asn.EcPublicKey, algorithm: EcKeyImportParams, extractable: boolean, keyUsages: KeyUsage[]) {
|
protected static async importPublicKey(asnKey: core.asn1.EcPublicKey, algorithm: EcKeyImportParams, extractable: boolean, keyUsages: KeyUsage[]) {
|
||||||
const keyInfo = new asn.PublicKeyInfo();
|
const keyInfo = new core.asn1.PublicKeyInfo();
|
||||||
keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.10045.2.1";
|
keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.10045.2.1";
|
||||||
keyInfo.publicKeyAlgorithm.parameters = AsnSerializer.serialize(new ObjectIdentifier(getOidByNamedCurve(algorithm.namedCurve)));
|
keyInfo.publicKeyAlgorithm.parameters = AsnSerializer.serialize(new core.asn1.ObjectIdentifier(getOidByNamedCurve(algorithm.namedCurve)));
|
||||||
keyInfo.publicKey = asnKey.value;
|
keyInfo.publicKey = asnKey.value;
|
||||||
|
|
||||||
const key = new EcPublicKey();
|
const key = new EcPublicKey();
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import { AsnParser, AsnSerializer } from "@peculiar/asn1-schema";
|
import { AsnParser, AsnSerializer } from "@peculiar/asn1-schema";
|
||||||
import { IJsonConvertible, JsonParser, JsonSerializer } from "@peculiar/json-schema";
|
import { IJsonConvertible, JsonParser, JsonSerializer } from "@peculiar/json-schema";
|
||||||
import * as core from "webcrypto-core";
|
import * as core from "webcrypto-core";
|
||||||
import * as asn from "../../asn";
|
|
||||||
import { ObjectIdentifier } from "../../asn";
|
|
||||||
import { AsymmetricKey } from "../../keys";
|
import { AsymmetricKey } from "../../keys";
|
||||||
import { getOidByNamedCurve } from "./helper";
|
import { getOidByNamedCurve } from "./helper";
|
||||||
|
|
||||||
|
@ -11,8 +9,8 @@ export class EcPrivateKey extends AsymmetricKey implements IJsonConvertible {
|
||||||
public algorithm!: EcKeyAlgorithm;
|
public algorithm!: EcKeyAlgorithm;
|
||||||
|
|
||||||
public getKey() {
|
public getKey() {
|
||||||
const keyInfo = AsnParser.parse(this.data, asn.PrivateKeyInfo);
|
const keyInfo = AsnParser.parse(this.data, core.asn1.PrivateKeyInfo);
|
||||||
return AsnParser.parse(keyInfo.privateKey, asn.EcPrivateKey);
|
return AsnParser.parse(keyInfo.privateKey, core.asn1.EcPrivateKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public toJSON() {
|
public toJSON() {
|
||||||
|
@ -33,12 +31,12 @@ export class EcPrivateKey extends AsymmetricKey implements IJsonConvertible {
|
||||||
throw new core.OperationError(`Cannot get named curve from JWK. Property 'crv' is required`);
|
throw new core.OperationError(`Cannot get named curve from JWK. Property 'crv' is required`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const keyInfo = new asn.PrivateKeyInfo();
|
const keyInfo = new core.asn1.PrivateKeyInfo();
|
||||||
keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.10045.2.1";
|
keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.10045.2.1";
|
||||||
keyInfo.privateKeyAlgorithm.parameters = AsnSerializer.serialize(
|
keyInfo.privateKeyAlgorithm.parameters = AsnSerializer.serialize(
|
||||||
new ObjectIdentifier(getOidByNamedCurve(json.crv)),
|
new core.asn1.ObjectIdentifier(getOidByNamedCurve(json.crv)),
|
||||||
);
|
);
|
||||||
const key = JsonParser.fromJSON(json, { targetSchema: asn.EcPrivateKey });
|
const key = JsonParser.fromJSON(json, { targetSchema: core.asn1.EcPrivateKey });
|
||||||
keyInfo.privateKey = AsnSerializer.serialize(key);
|
keyInfo.privateKey = AsnSerializer.serialize(key);
|
||||||
|
|
||||||
this.data = Buffer.from(AsnSerializer.serialize(keyInfo));
|
this.data = Buffer.from(AsnSerializer.serialize(keyInfo));
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import { AsnParser, AsnSerializer } from "@peculiar/asn1-schema";
|
import { AsnParser, AsnSerializer } from "@peculiar/asn1-schema";
|
||||||
import { IJsonConvertible, JsonParser, JsonSerializer } from "@peculiar/json-schema";
|
import { IJsonConvertible, JsonParser, JsonSerializer } from "@peculiar/json-schema";
|
||||||
import * as core from "webcrypto-core";
|
import * as core from "webcrypto-core";
|
||||||
import * as asn from "../../asn";
|
|
||||||
import { ObjectIdentifier } from "../../asn";
|
|
||||||
import { AsymmetricKey } from "../../keys/asymmetric";
|
import { AsymmetricKey } from "../../keys/asymmetric";
|
||||||
import { getOidByNamedCurve } from "./helper";
|
import { getOidByNamedCurve } from "./helper";
|
||||||
|
|
||||||
|
@ -12,8 +10,8 @@ export class EcPublicKey extends AsymmetricKey implements IJsonConvertible {
|
||||||
public algorithm!: EcKeyAlgorithm;
|
public algorithm!: EcKeyAlgorithm;
|
||||||
|
|
||||||
public getKey() {
|
public getKey() {
|
||||||
const keyInfo = AsnParser.parse(this.data, asn.PublicKeyInfo);
|
const keyInfo = AsnParser.parse(this.data, core.asn1.PublicKeyInfo);
|
||||||
return new asn.EcPublicKey(keyInfo.publicKey);
|
return new core.asn1.EcPublicKey(keyInfo.publicKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public toJSON() {
|
public toJSON() {
|
||||||
|
@ -34,12 +32,12 @@ export class EcPublicKey extends AsymmetricKey implements IJsonConvertible {
|
||||||
throw new core.OperationError(`Cannot get named curve from JWK. Property 'crv' is required`);
|
throw new core.OperationError(`Cannot get named curve from JWK. Property 'crv' is required`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const key = JsonParser.fromJSON(json, { targetSchema: asn.EcPublicKey });
|
const key = JsonParser.fromJSON(json, { targetSchema: core.asn1.EcPublicKey });
|
||||||
|
|
||||||
const keyInfo = new asn.PublicKeyInfo();
|
const keyInfo = new core.asn1.PublicKeyInfo();
|
||||||
keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.10045.2.1";
|
keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.10045.2.1";
|
||||||
keyInfo.publicKeyAlgorithm.parameters = AsnSerializer.serialize(
|
keyInfo.publicKeyAlgorithm.parameters = AsnSerializer.serialize(
|
||||||
new ObjectIdentifier(getOidByNamedCurve(json.crv)),
|
new core.asn1.ObjectIdentifier(getOidByNamedCurve(json.crv)),
|
||||||
);
|
);
|
||||||
keyInfo.publicKey = AsnSerializer.toASN(key).valueHex;
|
keyInfo.publicKey = AsnSerializer.toASN(key).valueHex;
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import crypto from "crypto";
|
||||||
import { AsnParser, AsnSerializer } from "@peculiar/asn1-schema";
|
import { AsnParser, AsnSerializer } from "@peculiar/asn1-schema";
|
||||||
import { JsonParser, JsonSerializer } from "@peculiar/json-schema";
|
import { JsonParser, JsonSerializer } from "@peculiar/json-schema";
|
||||||
import * as core from "webcrypto-core";
|
import * as core from "webcrypto-core";
|
||||||
import * as asn from "../../asn";
|
|
||||||
import { CryptoKey } from "../../keys";
|
import { CryptoKey } from "../../keys";
|
||||||
import { RsaPrivateKey } from "./private_key";
|
import { RsaPrivateKey } from "./private_key";
|
||||||
import { RsaPublicKey } from "./public_key";
|
import { RsaPublicKey } from "./public_key";
|
||||||
|
@ -77,21 +76,21 @@ export class RsaCrypto {
|
||||||
case "jwk": {
|
case "jwk": {
|
||||||
const jwk = keyData as JsonWebKey;
|
const jwk = keyData as JsonWebKey;
|
||||||
if (jwk.d) {
|
if (jwk.d) {
|
||||||
const asnKey = JsonParser.fromJSON(keyData, { targetSchema: asn.RsaPrivateKey });
|
const asnKey = JsonParser.fromJSON(keyData, { targetSchema: core.asn1.RsaPrivateKey });
|
||||||
return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages);
|
return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages);
|
||||||
} else {
|
} else {
|
||||||
const asnKey = JsonParser.fromJSON(keyData, { targetSchema: asn.RsaPublicKey });
|
const asnKey = JsonParser.fromJSON(keyData, { targetSchema: core.asn1.RsaPublicKey });
|
||||||
return this.importPublicKey(asnKey, algorithm, extractable, keyUsages);
|
return this.importPublicKey(asnKey, algorithm, extractable, keyUsages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "spki": {
|
case "spki": {
|
||||||
const keyInfo = AsnParser.parse(new Uint8Array(keyData as ArrayBuffer), asn.PublicKeyInfo);
|
const keyInfo = AsnParser.parse(new Uint8Array(keyData as ArrayBuffer), core.asn1.PublicKeyInfo);
|
||||||
const asnKey = AsnParser.parse(keyInfo.publicKey, asn.RsaPublicKey);
|
const asnKey = AsnParser.parse(keyInfo.publicKey, core.asn1.RsaPublicKey);
|
||||||
return this.importPublicKey(asnKey, algorithm, extractable, keyUsages);
|
return this.importPublicKey(asnKey, algorithm, extractable, keyUsages);
|
||||||
}
|
}
|
||||||
case "pkcs8": {
|
case "pkcs8": {
|
||||||
const keyInfo = AsnParser.parse(new Uint8Array(keyData as ArrayBuffer), asn.PrivateKeyInfo);
|
const keyInfo = AsnParser.parse(new Uint8Array(keyData as ArrayBuffer), core.asn1.PrivateKeyInfo);
|
||||||
const asnKey = AsnParser.parse(keyInfo.privateKey, asn.RsaPrivateKey);
|
const asnKey = AsnParser.parse(keyInfo.privateKey, core.asn1.RsaPrivateKey);
|
||||||
return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages);
|
return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -137,8 +136,8 @@ export class RsaCrypto {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static importPrivateKey(asnKey: asn.RsaPrivateKey, algorithm: RsaHashedImportParams, extractable: boolean, keyUsages: KeyUsage[]) {
|
protected static importPrivateKey(asnKey: core.asn1.RsaPrivateKey, algorithm: RsaHashedImportParams, extractable: boolean, keyUsages: KeyUsage[]) {
|
||||||
const keyInfo = new asn.PrivateKeyInfo();
|
const keyInfo = new core.asn1.PrivateKeyInfo();
|
||||||
keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1";
|
keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1";
|
||||||
keyInfo.privateKeyAlgorithm.parameters = null;
|
keyInfo.privateKeyAlgorithm.parameters = null;
|
||||||
keyInfo.privateKey = AsnSerializer.serialize(asnKey);
|
keyInfo.privateKey = AsnSerializer.serialize(asnKey);
|
||||||
|
@ -155,8 +154,8 @@ export class RsaCrypto {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static importPublicKey(asnKey: asn.RsaPublicKey, algorithm: RsaHashedImportParams, extractable: boolean, keyUsages: KeyUsage[]) {
|
protected static importPublicKey(asnKey: core.asn1.RsaPublicKey, algorithm: RsaHashedImportParams, extractable: boolean, keyUsages: KeyUsage[]) {
|
||||||
const keyInfo = new asn.PublicKeyInfo();
|
const keyInfo = new core.asn1.PublicKeyInfo();
|
||||||
keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1";
|
keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1";
|
||||||
keyInfo.publicKeyAlgorithm.parameters = null;
|
keyInfo.publicKeyAlgorithm.parameters = null;
|
||||||
keyInfo.publicKey = AsnSerializer.serialize(asnKey);
|
keyInfo.publicKey = AsnSerializer.serialize(asnKey);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { AsnParser, AsnSerializer } from "@peculiar/asn1-schema";
|
import { AsnParser, AsnSerializer } from "@peculiar/asn1-schema";
|
||||||
import { JsonParser, JsonSerializer } from "@peculiar/json-schema";
|
import { JsonParser, JsonSerializer } from "@peculiar/json-schema";
|
||||||
import * as asn from "../../asn";
|
import * as core from "webcrypto-core";
|
||||||
import { AsymmetricKey } from "../../keys";
|
import { AsymmetricKey } from "../../keys";
|
||||||
import { getJwkAlgorithm } from "./helper";
|
import { getJwkAlgorithm } from "./helper";
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@ export class RsaPrivateKey extends AsymmetricKey {
|
||||||
public algorithm!: RsaHashedKeyAlgorithm;
|
public algorithm!: RsaHashedKeyAlgorithm;
|
||||||
|
|
||||||
public getKey() {
|
public getKey() {
|
||||||
const keyInfo = AsnParser.parse(this.data, asn.PrivateKeyInfo);
|
const keyInfo = AsnParser.parse(this.data, core.asn1.PrivateKeyInfo);
|
||||||
return AsnParser.parse(keyInfo.privateKey, asn.RsaPrivateKey);
|
return AsnParser.parse(keyInfo.privateKey, core.asn1.RsaPrivateKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public toJSON() {
|
public toJSON() {
|
||||||
|
@ -27,9 +27,9 @@ export class RsaPrivateKey extends AsymmetricKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
public fromJSON(json: JsonWebKey) {
|
public fromJSON(json: JsonWebKey) {
|
||||||
const key = JsonParser.fromJSON(json, { targetSchema: asn.RsaPrivateKey });
|
const key = JsonParser.fromJSON(json, { targetSchema: core.asn1.RsaPrivateKey });
|
||||||
|
|
||||||
const keyInfo = new asn.PrivateKeyInfo();
|
const keyInfo = new core.asn1.PrivateKeyInfo();
|
||||||
keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1";
|
keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1";
|
||||||
keyInfo.privateKeyAlgorithm.parameters = null;
|
keyInfo.privateKeyAlgorithm.parameters = null;
|
||||||
keyInfo.privateKey = AsnSerializer.serialize(key);
|
keyInfo.privateKey = AsnSerializer.serialize(key);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { AsnParser, AsnSerializer } from "@peculiar/asn1-schema";
|
import { AsnParser, AsnSerializer } from "@peculiar/asn1-schema";
|
||||||
import { JsonParser, JsonSerializer } from "@peculiar/json-schema";
|
import { JsonParser, JsonSerializer } from "@peculiar/json-schema";
|
||||||
import * as asn from "../../asn";
|
import * as core from "webcrypto-core";
|
||||||
import { AsymmetricKey } from "../../keys/asymmetric";
|
import { AsymmetricKey } from "../../keys/asymmetric";
|
||||||
import { getJwkAlgorithm } from "./helper";
|
import { getJwkAlgorithm } from "./helper";
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@ export class RsaPublicKey extends AsymmetricKey {
|
||||||
public algorithm!: RsaHashedKeyAlgorithm;
|
public algorithm!: RsaHashedKeyAlgorithm;
|
||||||
|
|
||||||
public getKey() {
|
public getKey() {
|
||||||
const keyInfo = AsnParser.parse(this.data, asn.PublicKeyInfo);
|
const keyInfo = AsnParser.parse(this.data, core.asn1.PublicKeyInfo);
|
||||||
return AsnParser.parse(keyInfo.publicKey, asn.RsaPublicKey);
|
return AsnParser.parse(keyInfo.publicKey, core.asn1.RsaPublicKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public toJSON() {
|
public toJSON() {
|
||||||
|
@ -27,9 +27,9 @@ export class RsaPublicKey extends AsymmetricKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
public fromJSON(json: JsonWebKey) {
|
public fromJSON(json: JsonWebKey) {
|
||||||
const key = JsonParser.fromJSON(json, { targetSchema: asn.RsaPublicKey });
|
const key = JsonParser.fromJSON(json, { targetSchema: core.asn1.RsaPublicKey });
|
||||||
|
|
||||||
const keyInfo = new asn.PublicKeyInfo();
|
const keyInfo = new core.asn1.PublicKeyInfo();
|
||||||
keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1";
|
keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1";
|
||||||
keyInfo.publicKeyAlgorithm.parameters = null;
|
keyInfo.publicKeyAlgorithm.parameters = null;
|
||||||
keyInfo.publicKey = AsnSerializer.serialize(key);
|
keyInfo.publicKey = AsnSerializer.serialize(key);
|
||||||
|
|
114
test/asn.ts
114
test/asn.ts
|
@ -1,114 +0,0 @@
|
||||||
import assert from "assert";
|
|
||||||
import { AsnParser, AsnSerializer } from "@peculiar/asn1-schema";
|
|
||||||
import { JsonParser, JsonSerializer } from "@peculiar/json-schema";
|
|
||||||
import * as asn from "../src/asn";
|
|
||||||
|
|
||||||
context("ASN", () => {
|
|
||||||
|
|
||||||
context("RSA", () => {
|
|
||||||
|
|
||||||
context("PrivateKey", () => {
|
|
||||||
|
|
||||||
const bytes = Buffer.from("308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100faa3f76e5daf5dc288a54b7a99d7c7a9437581a184d80bb1aaf54cdfe245b28f52edb4db4888199e78ce993407bfd93c8102231b173eca09d44bb127c152b2e7f3a806852ed1dc323a1a33a5fecc0217ea98ddeb7068c14ffbbbd14a7904b3657a663ab76d2d88b10db77bc1b22e8881e58665508af0c31da225d08f3b07ad05bd8cf4d25943bffd3bb57d4266582276089e126db030d8ef04e0c30eeb65c325558d98bfc43b2b0c52212f3294d3ad7a91fa2ec2e838b2e73a4db616ec6aad5592dfc046f7e3589741fa0f4662fcf4ffca767611475f05272b3ddbd09b757b56f0293089d39e2cdd35722cd69ea00b3181e6e7c5e531f6608db3da31ce82afad02030100010282010025698d3901adf8125e204244822b45e7dba4721da07d393da375ab2c6e139644338e3ce5508dd43925f23cc719f306a3b3e414466a715a6a1e30d0384d70a138e3536ce9bb63e2f8f2584fe652c2b3fb4aeed78d59c1a13d65a792e5896becb5549066ea53572d24b495f358a5d6b154a664a9c1dc8374b47b2c26d6026b3265b1d6e4448bd2253ce467ae99017c53af1fb085cdd5c8dc3cc66941beaa480295e907a936776f49e5e619d5e2e89e5a1bf220121c965b08b658d669464a4d0eb414efe11c8fa20987fae0758542ec69a9d335b01a78b8770b499272105629b4e81f04065644928f0b01bfb0294fbeb0e0e4e3ad6129d356fce820d35171126b1702818100fe042d914643ad84d8e5a0d0c3c7dc9b35ac60d96ef9305e74ead8419a1937c3a4d5b6b2d589f818ab0cfa4f6ee12fbeb85f7c117ba4eb489b31f0eecac4f8368b52b3339043a3160fa3535e1e45634947b582438149b062b73029bd2279793154153da0e120c48fe71c466783e6537ea9157d776bedd272e08fe4e961fe14ff02818100fc990a2846cf6c0f38ad798855a81f2386795425523f99a8660968be450564d97d62b58533bb9e65c36d56d28480b39bbbfaf7ddfdb8b08aa080740038b1786e659dfb342cdf197bcb8c40af1719814c734cec50b3e915cf927b6eb8e880d4073ab2d6c1e106c78e5add9042476f78edfb76d2d7ef5e1ae4c33f51c558691f5302818100b4a329f86e5c40700182427b534eb4add75c6f3f10b0ba59e191041a9ac82624c5fa88c2e2220c41169ad3025bda5d86a63c98d121f964ac2c593679c9ce8aa8d7290770babdaea348999ff6855658c5caede3e5b7723cb1e68da490f08c2bc80d8051642fd48a93bf09177413935e7aeb28f22153aa3b0720749397f7eca4e702818067661215589f11c1cd569d98245014a70b25e13f01c30d1834e4871ed3cc18733af34c10c1937c8c7589ed6f7153e9b1c72a3d8a7e90ba9b9485e07632bedae87dea44692031171268c8f9b572843b3c5b3a52c5da4f80611eba2e21bcf2f7581a3c18d2f6553b1cd7af389d18f6d58ebd4fef90fae80fa433145959aa0e260702818045ef370e79be4352cae716a92244f37f0b4a5133442b49de4a8bc5342d40a00eed284dcb5061d6dcde01baa12fde1ee965f66acabf58bd08d2f78c8f5f00a9156242ea971940611c8f9892335e48e211d2667aa0c5186af712cbab48802f2fc37488316e72d8dfd28a9e311e962fba79324e14d61a61d4afc4646da76dc650ae", "hex");
|
|
||||||
const json = {
|
|
||||||
d: "JWmNOQGt-BJeIEJEgitF59ukch2gfTk9o3WrLG4TlkQzjjzlUI3UOSXyPMcZ8wajs-QURmpxWmoeMNA4TXChOONTbOm7Y-L48lhP5lLCs_tK7teNWcGhPWWnkuWJa-y1VJBm6lNXLSS0lfNYpdaxVKZkqcHcg3S0eywm1gJrMmWx1uREi9IlPORnrpkBfFOvH7CFzdXI3DzGaUG-qkgClekHqTZ3b0nl5hnV4uieWhvyIBIcllsItljWaUZKTQ60FO_hHI-iCYf64HWFQuxpqdM1sBp4uHcLSZJyEFYptOgfBAZWRJKPCwG_sClPvrDg5OOtYSnTVvzoINNRcRJrFw",
|
|
||||||
dp: "tKMp-G5cQHABgkJ7U060rddcbz8QsLpZ4ZEEGprIJiTF-ojC4iIMQRaa0wJb2l2GpjyY0SH5ZKwsWTZ5yc6KqNcpB3C6va6jSJmf9oVWWMXK7ePlt3I8seaNpJDwjCvIDYBRZC_UipO_CRd0E5Neeuso8iFTqjsHIHSTl_fspOc",
|
|
||||||
dq: "Z2YSFVifEcHNVp2YJFAUpwsl4T8Bww0YNOSHHtPMGHM680wQwZN8jHWJ7W9xU-mxxyo9in6QupuUheB2Mr7a6H3qRGkgMRcSaMj5tXKEOzxbOlLF2k-AYR66LiG88vdYGjwY0vZVOxzXrzidGPbVjr1P75D66A-kMxRZWaoOJgc",
|
|
||||||
e: "AQAB",
|
|
||||||
n: "-qP3bl2vXcKIpUt6mdfHqUN1gaGE2AuxqvVM3-JFso9S7bTbSIgZnnjOmTQHv9k8gQIjGxc-ygnUS7EnwVKy5_OoBoUu0dwyOhozpf7MAhfqmN3rcGjBT_u70Up5BLNlemY6t20tiLENt3vBsi6IgeWGZVCK8MMdoiXQjzsHrQW9jPTSWUO__Tu1fUJmWCJ2CJ4SbbAw2O8E4MMO62XDJVWNmL_EOysMUiEvMpTTrXqR-i7C6Diy5zpNthbsaq1Vkt_ARvfjWJdB-g9GYvz0_8p2dhFHXwUnKz3b0Jt1e1bwKTCJ054s3TVyLNaeoAsxgebnxeUx9mCNs9oxzoKvrQ",
|
|
||||||
p: "_gQtkUZDrYTY5aDQw8fcmzWsYNlu-TBedOrYQZoZN8Ok1bay1Yn4GKsM-k9u4S--uF98EXuk60ibMfDuysT4NotSszOQQ6MWD6NTXh5FY0lHtYJDgUmwYrcwKb0ieXkxVBU9oOEgxI_nHEZng-ZTfqkVfXdr7dJy4I_k6WH-FP8",
|
|
||||||
q: "_JkKKEbPbA84rXmIVagfI4Z5VCVSP5moZglovkUFZNl9YrWFM7ueZcNtVtKEgLObu_r33f24sIqggHQAOLF4bmWd-zQs3xl7y4xArxcZgUxzTOxQs-kVz5J7brjogNQHOrLWweEGx45a3ZBCR2947ft20tfvXhrkwz9RxVhpH1M",
|
|
||||||
qi: "Re83Dnm-Q1LK5xapIkTzfwtKUTNEK0neSovFNC1AoA7tKE3LUGHW3N4BuqEv3h7pZfZqyr9YvQjS94yPXwCpFWJC6pcZQGEcj5iSM15I4hHSZnqgxRhq9xLLq0iALy_DdIgxbnLY39KKnjEeli-6eTJOFNYaYdSvxGRtp23GUK4",
|
|
||||||
};
|
|
||||||
|
|
||||||
it("parse", () => {
|
|
||||||
const keyInfo = AsnParser.parse(bytes, asn.PrivateKeyInfo);
|
|
||||||
const key = AsnParser.parse(keyInfo.privateKey, asn.RsaPrivateKey);
|
|
||||||
|
|
||||||
const jsonKey = JsonSerializer.toJSON(key);
|
|
||||||
assert.deepEqual(jsonKey, json);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("serialize", () => {
|
|
||||||
const key = JsonParser.fromJSON(json, { targetSchema: asn.RsaPrivateKey });
|
|
||||||
|
|
||||||
const keyInfo = new asn.PrivateKeyInfo();
|
|
||||||
keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1";
|
|
||||||
keyInfo.privateKeyAlgorithm.parameters = null;
|
|
||||||
keyInfo.privateKey = AsnSerializer.serialize(key);
|
|
||||||
|
|
||||||
const asnKeyInfo = Buffer.from(AsnSerializer.serialize(keyInfo));
|
|
||||||
assert.equal(asnKeyInfo.equals(bytes), true);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
context("PublicKey", () => {
|
|
||||||
|
|
||||||
const bytes = Buffer.from("30820122300d06092a864886f70d01010105000382010f003082010a0282010100faa3f76e5daf5dc288a54b7a99d7c7a9437581a184d80bb1aaf54cdfe245b28f52edb4db4888199e78ce993407bfd93c8102231b173eca09d44bb127c152b2e7f3a806852ed1dc323a1a33a5fecc0217ea98ddeb7068c14ffbbbd14a7904b3657a663ab76d2d88b10db77bc1b22e8881e58665508af0c31da225d08f3b07ad05bd8cf4d25943bffd3bb57d4266582276089e126db030d8ef04e0c30eeb65c325558d98bfc43b2b0c52212f3294d3ad7a91fa2ec2e838b2e73a4db616ec6aad5592dfc046f7e3589741fa0f4662fcf4ffca767611475f05272b3ddbd09b757b56f0293089d39e2cdd35722cd69ea00b3181e6e7c5e531f6608db3da31ce82afad0203010001", "hex");
|
|
||||||
const json = {
|
|
||||||
n: "-qP3bl2vXcKIpUt6mdfHqUN1gaGE2AuxqvVM3-JFso9S7bTbSIgZnnjOmTQHv9k8gQIjGxc-ygnUS7EnwVKy5_OoBoUu0dwyOhozpf7MAhfqmN3rcGjBT_u70Up5BLNlemY6t20tiLENt3vBsi6IgeWGZVCK8MMdoiXQjzsHrQW9jPTSWUO__Tu1fUJmWCJ2CJ4SbbAw2O8E4MMO62XDJVWNmL_EOysMUiEvMpTTrXqR-i7C6Diy5zpNthbsaq1Vkt_ARvfjWJdB-g9GYvz0_8p2dhFHXwUnKz3b0Jt1e1bwKTCJ054s3TVyLNaeoAsxgebnxeUx9mCNs9oxzoKvrQ",
|
|
||||||
e: "AQAB",
|
|
||||||
};
|
|
||||||
|
|
||||||
it("parse", () => {
|
|
||||||
const keyInfo = AsnParser.parse(bytes, asn.PublicKeyInfo);
|
|
||||||
const key = AsnParser.parse(keyInfo.publicKey, asn.RsaPublicKey);
|
|
||||||
|
|
||||||
const jsonKey = JsonSerializer.toJSON(key);
|
|
||||||
assert.deepEqual(jsonKey, json);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("serialize", () => {
|
|
||||||
const key = JsonParser.fromJSON(json, { targetSchema: asn.RsaPublicKey });
|
|
||||||
|
|
||||||
const keyInfo = new asn.PublicKeyInfo();
|
|
||||||
keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.113549.1.1.1";
|
|
||||||
keyInfo.publicKeyAlgorithm.parameters = null;
|
|
||||||
keyInfo.publicKey = AsnSerializer.serialize(key);
|
|
||||||
|
|
||||||
const asnKeyInfo = Buffer.from(AsnSerializer.serialize(keyInfo));
|
|
||||||
assert.equal(asnKeyInfo.equals(bytes), true);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
context("EC", () => {
|
|
||||||
|
|
||||||
context("PrivateKey", () => {
|
|
||||||
|
|
||||||
const bytes = Buffer.from("308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420db0964fc2a963e9a2aef561f57db3556fa87e83ceb2e5f6dc84b00c18aa873e3a144034200043266c1386af7a0993b169393df1f7c4016e27fd48642e8d512c775b31c8f06722baef1310974a6c63aff2ef8832fba27f021f5ae2f2c6c2d56fde5be5ade78f5", "hex");
|
|
||||||
const json = {
|
|
||||||
d: "2wlk_CqWPpoq71YfV9s1VvqH6DzrLl9tyEsAwYqoc-M",
|
|
||||||
x: "MmbBOGr3oJk7FpOT3x98QBbif9SGQujVEsd1sxyPBnI",
|
|
||||||
y: "K67xMQl0psY6_y74gy-6J_Ah9a4vLGwtVv3lvlreePU",
|
|
||||||
};
|
|
||||||
|
|
||||||
it("parse", () => {
|
|
||||||
const keyInfo = AsnParser.parse(bytes, asn.PrivateKeyInfo);
|
|
||||||
const key = AsnParser.parse(keyInfo.privateKey, asn.EcPrivateKey);
|
|
||||||
|
|
||||||
const jsonKey = JsonSerializer.toJSON(key);
|
|
||||||
assert.deepEqual(jsonKey, json);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("serialize", () => {
|
|
||||||
const keyInfo = new asn.PrivateKeyInfo();
|
|
||||||
keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.10045.2.1";
|
|
||||||
keyInfo.privateKeyAlgorithm.parameters = AsnSerializer.serialize(
|
|
||||||
new asn.ObjectIdentifier("1.2.840.10045.3.1.7"),
|
|
||||||
);
|
|
||||||
const key = JsonParser.fromJSON(json, { targetSchema: asn.EcPrivateKey });
|
|
||||||
keyInfo.privateKey = AsnSerializer.serialize(key);
|
|
||||||
|
|
||||||
const asnKeyInfo = Buffer.from(AsnSerializer.serialize(keyInfo));
|
|
||||||
assert.equal(asnKeyInfo.equals(bytes), true);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
Reference in New Issue