mirror of
https://github.com/selfxyz/self.git
synced 2026-04-05 03:00:53 -04:00
split parseCertificateSimple.ts
This commit is contained in:
@@ -7,7 +7,7 @@ import { getIssuerCountryCode, getSubjectKeyIdentifier } from "./utils";
|
||||
import fs from 'fs';
|
||||
import { execSync } from 'child_process';
|
||||
import { getAuthorityKeyIdentifier } from "../certificates/handleCertificate";
|
||||
|
||||
import { parseCertificateSimple } from "./parseCertificateSimple";
|
||||
export function parseCertificate(pem: string, fileName: string): any {
|
||||
let certificateData: CertificateData = {
|
||||
id: '',
|
||||
@@ -48,95 +48,7 @@ export function parseCertificate(pem: string, fileName: string): any {
|
||||
}
|
||||
|
||||
|
||||
export function parseCertificateSimple(pem: string): any {
|
||||
let certificateData: CertificateData = {
|
||||
id: '',
|
||||
issuer: '',
|
||||
validity: {
|
||||
notBefore: '',
|
||||
notAfter: ''
|
||||
},
|
||||
subjectKeyIdentifier: '',
|
||||
authorityKeyIdentifier: '',
|
||||
signatureAlgorithm: '',
|
||||
hashAlgorithm: '',
|
||||
publicKeyDetails: undefined,
|
||||
rawPem: '',
|
||||
rawTxt: ''
|
||||
};
|
||||
try {
|
||||
const pemFormatted = pem.replace(/(-----(BEGIN|END) CERTIFICATE-----|\n|\r)/g, "");
|
||||
const binary = Buffer.from(pemFormatted, "base64");
|
||||
const arrayBuffer = new ArrayBuffer(binary.length);
|
||||
const view = new Uint8Array(arrayBuffer);
|
||||
for (let i = 0; i < binary.length; i++) {
|
||||
view[i] = binary[i];
|
||||
}
|
||||
|
||||
const asn1 = asn1js.fromBER(arrayBuffer);
|
||||
if (asn1.offset === -1) {
|
||||
throw new Error(`ASN.1 parsing error: ${asn1.result.error}`);
|
||||
}
|
||||
|
||||
const cert = new Certificate({ schema: asn1.result });
|
||||
const publicKeyAlgoOID = cert.subjectPublicKeyInfo.algorithm.algorithmId;
|
||||
const publicKeyAlgoFN = getFriendlyName(publicKeyAlgoOID);
|
||||
const signatureAlgoOID = cert.signatureAlgorithm.algorithmId;
|
||||
const signatureAlgoFN = getFriendlyName(signatureAlgoOID);
|
||||
|
||||
|
||||
let params;
|
||||
if (publicKeyAlgoFN === 'RSA') {
|
||||
if (signatureAlgoFN === 'RSASSA_PSS') {
|
||||
certificateData.signatureAlgorithm = "rsapss";
|
||||
params = getParamsRSAPSS(cert);
|
||||
certificateData.hashAlgorithm = (params as PublicKeyDetailsRSAPSS).hashAlgorithm;
|
||||
}
|
||||
else {
|
||||
certificateData.hashAlgorithm = extractHashFunction(signatureAlgoFN);
|
||||
certificateData.signatureAlgorithm = "rsa";
|
||||
params = getParamsRSA(cert);
|
||||
}
|
||||
|
||||
}
|
||||
else if (publicKeyAlgoFN === 'ECC') {
|
||||
certificateData.hashAlgorithm = extractHashFunction(signatureAlgoFN);
|
||||
certificateData.signatureAlgorithm = "ecdsa";
|
||||
params = getParamsECDSA(cert);
|
||||
}
|
||||
else if (publicKeyAlgoFN === 'RSASSA_PSS') {
|
||||
certificateData.signatureAlgorithm = "rsapss";
|
||||
//different certificate structure than the RSA/RSAPSS mix, we can't retrieve the modulus the same way as for RSA
|
||||
// console.log(cert);
|
||||
|
||||
//TODO: implement the parsing of the RSASSA_PSS certificate
|
||||
params = getParamsRSAPSS2(cert);
|
||||
}
|
||||
else {
|
||||
console.log(publicKeyAlgoFN);
|
||||
}
|
||||
certificateData.publicKeyDetails = params;
|
||||
certificateData.issuer = getIssuerCountryCode(cert);;
|
||||
certificateData.validity = {
|
||||
notBefore: cert.notBefore.value.toString(),
|
||||
notAfter: cert.notAfter.value.toString()
|
||||
};
|
||||
const ski = getSubjectKeyIdentifier(cert);
|
||||
certificateData.id = ski.slice(0, 12);
|
||||
certificateData.subjectKeyIdentifier = ski;
|
||||
certificateData.rawPem = pem;
|
||||
|
||||
const authorityKeyIdentifier = getAuthorityKeyIdentifier(cert);
|
||||
certificateData.authorityKeyIdentifier = authorityKeyIdentifier;
|
||||
|
||||
return certificateData;
|
||||
|
||||
} catch (error) {
|
||||
console.error(`Error processing certificate`, error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function getParamsRSA(cert: Certificate): PublicKeyDetailsRSA {
|
||||
const publicKeyValue = cert.subjectPublicKeyInfo.parsedKey as RSAPublicKey;
|
||||
|
||||
234
common/src/utils/certificate_parsing/parseCertificateSimple.ts
Normal file
234
common/src/utils/certificate_parsing/parseCertificateSimple.ts
Normal file
@@ -0,0 +1,234 @@
|
||||
import * as asn1js from "asn1js";
|
||||
import { Certificate, RSAPublicKey, RSASSAPSSParams } from "pkijs";
|
||||
import { extractHashFunction, getFriendlyName } from "./oids";
|
||||
import { CertificateData, PublicKeyDetailsECDSA, PublicKeyDetailsRSA, PublicKeyDetailsRSAPSS } from "./dataStructure";
|
||||
import { getECDSACurveBits, identifyCurve, StandardCurve } from "./curves";
|
||||
import { getIssuerCountryCode, getSubjectKeyIdentifier } from "./utils";
|
||||
import { getAuthorityKeyIdentifier } from "../certificates/handleCertificate";
|
||||
|
||||
|
||||
export function parseCertificateSimple(pem: string): any {
|
||||
let certificateData: CertificateData = {
|
||||
id: '',
|
||||
issuer: '',
|
||||
validity: {
|
||||
notBefore: '',
|
||||
notAfter: ''
|
||||
},
|
||||
subjectKeyIdentifier: '',
|
||||
authorityKeyIdentifier: '',
|
||||
signatureAlgorithm: '',
|
||||
hashAlgorithm: '',
|
||||
publicKeyDetails: undefined,
|
||||
rawPem: '',
|
||||
rawTxt: ''
|
||||
};
|
||||
try {
|
||||
const pemFormatted = pem.replace(/(-----(BEGIN|END) CERTIFICATE-----|\n|\r)/g, "");
|
||||
const binary = Buffer.from(pemFormatted, "base64");
|
||||
const arrayBuffer = new ArrayBuffer(binary.length);
|
||||
const view = new Uint8Array(arrayBuffer);
|
||||
for (let i = 0; i < binary.length; i++) {
|
||||
view[i] = binary[i];
|
||||
}
|
||||
|
||||
const asn1 = asn1js.fromBER(arrayBuffer);
|
||||
if (asn1.offset === -1) {
|
||||
throw new Error(`ASN.1 parsing error: ${asn1.result.error}`);
|
||||
}
|
||||
|
||||
const cert = new Certificate({ schema: asn1.result });
|
||||
const publicKeyAlgoOID = cert.subjectPublicKeyInfo.algorithm.algorithmId;
|
||||
const publicKeyAlgoFN = getFriendlyName(publicKeyAlgoOID);
|
||||
const signatureAlgoOID = cert.signatureAlgorithm.algorithmId;
|
||||
const signatureAlgoFN = getFriendlyName(signatureAlgoOID);
|
||||
|
||||
|
||||
let params;
|
||||
if (publicKeyAlgoFN === 'RSA') {
|
||||
if (signatureAlgoFN === 'RSASSA_PSS') {
|
||||
certificateData.signatureAlgorithm = "rsapss";
|
||||
params = getParamsRSAPSS(cert);
|
||||
certificateData.hashAlgorithm = (params as PublicKeyDetailsRSAPSS).hashAlgorithm;
|
||||
}
|
||||
else {
|
||||
certificateData.hashAlgorithm = extractHashFunction(signatureAlgoFN);
|
||||
certificateData.signatureAlgorithm = "rsa";
|
||||
params = getParamsRSA(cert);
|
||||
}
|
||||
|
||||
}
|
||||
else if (publicKeyAlgoFN === 'ECC') {
|
||||
certificateData.hashAlgorithm = extractHashFunction(signatureAlgoFN);
|
||||
certificateData.signatureAlgorithm = "ecdsa";
|
||||
params = getParamsECDSA(cert);
|
||||
}
|
||||
else if (publicKeyAlgoFN === 'RSASSA_PSS') {
|
||||
certificateData.signatureAlgorithm = "rsapss";
|
||||
//different certificate structure than the RSA/RSAPSS mix, we can't retrieve the modulus the same way as for RSA
|
||||
// console.log(cert);
|
||||
|
||||
//TODO: implement the parsing of the RSASSA_PSS certificate
|
||||
params = getParamsRSAPSS2(cert);
|
||||
}
|
||||
else {
|
||||
console.log(publicKeyAlgoFN);
|
||||
}
|
||||
certificateData.publicKeyDetails = params;
|
||||
certificateData.issuer = getIssuerCountryCode(cert);;
|
||||
certificateData.validity = {
|
||||
notBefore: cert.notBefore.value.toString(),
|
||||
notAfter: cert.notAfter.value.toString()
|
||||
};
|
||||
const ski = getSubjectKeyIdentifier(cert);
|
||||
certificateData.id = ski.slice(0, 12);
|
||||
certificateData.subjectKeyIdentifier = ski;
|
||||
certificateData.rawPem = pem;
|
||||
|
||||
const authorityKeyIdentifier = getAuthorityKeyIdentifier(cert);
|
||||
certificateData.authorityKeyIdentifier = authorityKeyIdentifier;
|
||||
|
||||
return certificateData;
|
||||
|
||||
} catch (error) {
|
||||
console.error(`Error processing certificate`, error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function getParamsRSA(cert: Certificate): PublicKeyDetailsRSA {
|
||||
const publicKeyValue = cert.subjectPublicKeyInfo.parsedKey as RSAPublicKey;
|
||||
const modulusBytes = publicKeyValue.modulus.valueBlock.valueHexView;
|
||||
const modulusHex = Buffer.from(modulusBytes).toString('hex');
|
||||
const exponentBigInt = publicKeyValue.publicExponent.toBigInt();
|
||||
const exponentDecimal = exponentBigInt.toString();
|
||||
const actualBits = modulusBytes.length * 8;
|
||||
|
||||
return {
|
||||
modulus: modulusHex,
|
||||
exponent: exponentDecimal,
|
||||
bits: actualBits.toString()
|
||||
};
|
||||
}
|
||||
|
||||
function getParamsRSAPSS(cert: Certificate): PublicKeyDetailsRSAPSS {
|
||||
const { modulus, exponent, bits } = getParamsRSA(cert);
|
||||
const sigAlgParams = cert.signatureAlgorithm.algorithmParams;
|
||||
const pssParams = new RSASSAPSSParams({ schema: sigAlgParams });
|
||||
const hashAlgorithm = getFriendlyName(pssParams.hashAlgorithm.algorithmId);
|
||||
const mgf = getFriendlyName(pssParams.maskGenAlgorithm.algorithmId);
|
||||
|
||||
return {
|
||||
modulus: modulus,
|
||||
exponent: exponent,
|
||||
bits: bits,
|
||||
hashAlgorithm: hashAlgorithm,
|
||||
mgf: mgf,
|
||||
saltLength: pssParams.saltLength.toString()
|
||||
};
|
||||
}
|
||||
|
||||
function getParamsRSAPSS2(cert: Certificate): PublicKeyDetailsRSAPSS {
|
||||
// Get the subjectPublicKey BitString
|
||||
const spki = cert.subjectPublicKeyInfo;
|
||||
const spkiValueHex = spki.subjectPublicKey.valueBlock.valueHexView;
|
||||
|
||||
// Parse the public key ASN.1 structure
|
||||
const asn1PublicKey = asn1js.fromBER(spkiValueHex);
|
||||
if (asn1PublicKey.offset === -1) {
|
||||
throw new Error("Error parsing public key ASN.1 structure");
|
||||
}
|
||||
|
||||
// The public key is an RSAPublicKey structure
|
||||
const rsaPublicKey = new RSAPublicKey({ schema: asn1PublicKey.result });
|
||||
const modulusBytes = rsaPublicKey.modulus.valueBlock.valueHexView;
|
||||
const modulusHex = Buffer.from(modulusBytes).toString('hex');
|
||||
const exponentBigInt = rsaPublicKey.publicExponent.toBigInt();
|
||||
const exponentDecimal = exponentBigInt.toString();
|
||||
const actualBits = modulusBytes.length * 8;
|
||||
|
||||
const sigAlgParams = cert.signatureAlgorithm.algorithmParams;
|
||||
const pssParams = new RSASSAPSSParams({ schema: sigAlgParams });
|
||||
const hashAlgorithm = getFriendlyName(pssParams.hashAlgorithm.algorithmId);
|
||||
const mgf = getFriendlyName(pssParams.maskGenAlgorithm.algorithmId);
|
||||
|
||||
return {
|
||||
modulus: modulusHex,
|
||||
exponent: exponentDecimal,
|
||||
bits: actualBits.toString(),
|
||||
hashAlgorithm: hashAlgorithm,
|
||||
mgf: mgf,
|
||||
saltLength: pssParams.saltLength.toString()
|
||||
};
|
||||
}
|
||||
|
||||
export function getParamsECDSA(cert: Certificate): PublicKeyDetailsECDSA {
|
||||
try {
|
||||
const algorithmParams = cert.subjectPublicKeyInfo.algorithm.algorithmParams;
|
||||
if (!algorithmParams) {
|
||||
console.log('No algorithm params found');
|
||||
return { curve: 'Unknown', params: {} as StandardCurve, bits: 'Unknown' };
|
||||
}
|
||||
|
||||
const params = asn1js.fromBER(algorithmParams.valueBeforeDecodeView).result;
|
||||
const valueBlock: any = params.valueBlock;
|
||||
|
||||
if (valueBlock.value && valueBlock.value.length >= 5) {
|
||||
const curveParams: StandardCurve = {} as StandardCurve;
|
||||
// Field ID (index 1)
|
||||
const fieldId = valueBlock.value[1];
|
||||
if (fieldId && fieldId.valueBlock && fieldId.valueBlock.value) {
|
||||
const fieldType = fieldId.valueBlock.value[0];
|
||||
const prime = fieldId.valueBlock.value[1];
|
||||
//curveParams.fieldType = fieldType.valueBlock.toString();
|
||||
curveParams.p = Buffer.from(prime.valueBlock.valueHexView).toString('hex');
|
||||
}
|
||||
|
||||
// Curve Coefficients (index 2)
|
||||
const curveCoefficients = valueBlock.value[2];
|
||||
if (curveCoefficients && curveCoefficients.valueBlock && curveCoefficients.valueBlock.value) {
|
||||
const a = curveCoefficients.valueBlock.value[0];
|
||||
const b = curveCoefficients.valueBlock.value[1];
|
||||
curveParams.a = Buffer.from(a.valueBlock.valueHexView).toString('hex');
|
||||
curveParams.b = Buffer.from(b.valueBlock.valueHexView).toString('hex');
|
||||
}
|
||||
|
||||
// Base Point G (index 3)
|
||||
const basePoint = valueBlock.value[3];
|
||||
if (basePoint && basePoint.valueBlock) {
|
||||
curveParams.G = Buffer.from(basePoint.valueBlock.valueHexView).toString('hex');
|
||||
}
|
||||
|
||||
// Order n (index 4)
|
||||
const order = valueBlock.value[4];
|
||||
if (order && order.valueBlock) {
|
||||
curveParams.n = Buffer.from(order.valueBlock.valueHexView).toString('hex');
|
||||
}
|
||||
|
||||
if (valueBlock.value.length >= 6) {
|
||||
// Cofactor h (index 5)
|
||||
const cofactor = valueBlock.value[5];
|
||||
if (cofactor && cofactor.valueBlock) {
|
||||
curveParams.h = Buffer.from(cofactor.valueBlock.valueHexView).toString('hex');
|
||||
}
|
||||
}
|
||||
else {
|
||||
curveParams.h = '01';
|
||||
}
|
||||
|
||||
const identifiedCurve = identifyCurve(curveParams);
|
||||
return { curve: identifiedCurve, params: curveParams, bits: getECDSACurveBits(identifiedCurve) };
|
||||
} else {
|
||||
if (valueBlock.value) {
|
||||
console.log(valueBlock.value);
|
||||
}
|
||||
else {
|
||||
console.log('No value block found');
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error parsing EC parameters:', error);
|
||||
return { curve: 'Error', params: {} as StandardCurve, bits: 'Unknown' };
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import { poseidon2 } from 'poseidon-lite';
|
||||
import { IMT } from '@openpassport/zk-kit-imt';
|
||||
import serialized_csca_tree from '../../pubkeys/serialized_csca_tree.json';
|
||||
import axios from 'axios';
|
||||
import { parseCertificate, parseCertificateSimple } from './certificate_parsing/parseCertificate';
|
||||
import { parseCertificateSimple } from './certificate_parsing/parseCertificateSimple';
|
||||
import { getLeafCSCA } from './pubkeyTree';
|
||||
import { SKI_PEM, SKI_PEM_DEV } from '../constants/skiPem';
|
||||
import { CertificateData, PublicKeyDetailsRSA } from './certificate_parsing/dataStructure';
|
||||
|
||||
Reference in New Issue
Block a user