update scripts

This commit is contained in:
turnoffthiscomputer
2024-08-17 14:24:50 +02:00
parent 2ae175abfd
commit 84819a4b9d
9 changed files with 179 additions and 229 deletions

38
registry/src/buildJson.ts Normal file
View File

@@ -0,0 +1,38 @@
import fs from 'fs';
import path from 'path';
import { getRegistryJson } from './utils/getRegistryJson';
import { getMapJson } from './utils/getMapJson';
import { getSkiModulusJson } from './utils/getSkiModulusJson';
const csca_pem_directory_path = path.join(__dirname, '..', 'outputs', 'unique_pem_masterlist');
const dsc_pem_directory_path = path.join(__dirname, '..', 'outputs', 'dsc', 'pem_masterlist');
const searchable_registry_csca_path = path.join(__dirname, '..', 'outputs', 'searchable_registry_csca.json');
const searchable_registry_dsc_path = path.join(__dirname, '..', 'outputs', 'searchable_registry_dsc.json');
const map_csca_path = path.join(__dirname, '..', 'outputs', 'map_csca.json');
const map_dsc_path = path.join(__dirname, '..', 'outputs', 'map_dsc.json');
const ski_modulus_path = path.join(__dirname, '..', 'outputs', 'ski_modulus.json');
async function main() {
console.log('\x1b[32m', 'building SKI modulus JSON', '\x1b[0m');
const skiModulusJson = await getSkiModulusJson(csca_pem_directory_path);
fs.writeFileSync(ski_modulus_path, JSON.stringify(skiModulusJson, null, 2));
console.log('\x1b[32m', 'building searchable registry JSON', '\x1b[0m');
const searchable_registry_csca = await getRegistryJson(csca_pem_directory_path);
fs.writeFileSync(searchable_registry_csca_path, JSON.stringify(searchable_registry_csca, null, 2));
const searchable_registry_dsc = await getRegistryJson(dsc_pem_directory_path);
fs.writeFileSync(searchable_registry_dsc_path, JSON.stringify(searchable_registry_dsc, null, 2));
console.log('\x1b[32m', 'building map JSON', '\x1b[0m');
const map_csca = await getMapJson(csca_pem_directory_path);
fs.writeFileSync(map_csca_path, JSON.stringify(map_csca, null, 2));
const map_dsc = await getMapJson(dsc_pem_directory_path);
fs.writeFileSync(map_dsc_path, JSON.stringify(map_dsc, null, 2));
}
main().catch(console.error);

View File

@@ -1,200 +0,0 @@
import * as fs from 'fs';
import { buildPubkeyTree } from '../../../common/src/utils/pubkeyTree'
import { computeLeafFromModulusBigInt } from '../../../common/src/utils/csca'
import { CSCA_AKI_MODULUS, CSCA_TREE_DEPTH, DEVELOPMENT_MODE } from '../../../common/src/constants/constants';
import { IMT } from '@zk-kit/imt';
import { poseidon2 } from 'poseidon-lite';
import { splitToWords } from '../../../common/src/utils/utils';
import { writeFile } from 'fs/promises';
import * as path from 'path';
import jsrsasign from 'jsrsasign';
import * as asn1 from 'asn1.js';
const RSAPublicKey = asn1.define('RSAPublicKey', function () {
this.seq().obj(
this.key('n').int(),
this.key('e').int()
);
});
function isRsaPublicKey(key) {
return key.type === 'RSA' || key.type === 'RSA-PSS';
}
function getPublicKey(certificate) {
const publicKeyInfo = certificate.getPublicKeyHex();
try {
// Try to parse the public key as ASN.1
const publicKeyAsn1 = asn1.define('PublicKey', function () {
this.seq().obj(
this.key('algorithm').seq().obj(
this.key('algorithmId').objid(),
this.key('parameters').optional().any()
),
this.key('publicKey').bitstr()
);
});
const parsed = publicKeyAsn1.decode(Buffer.from(publicKeyInfo, 'hex'), 'der');
const publicKeyBuffer = parsed.publicKey.data;
// Parse the RSA public key
const rsaPublicKey = RSAPublicKey.decode(publicKeyBuffer, 'der');
return {
n: new jsrsasign.BigInteger(rsaPublicKey.n.toString('hex'), 16),
e: new jsrsasign.BigInteger(rsaPublicKey.e.toString('hex'), 16),
type: 'RSA'
};
} catch (e) {
console.error("Error parsing public key:", e);
}
// If parsing fails, fall back to manual extraction
const modulus = extractModulus(publicKeyInfo);
if (modulus) {
return { n: new jsrsasign.BigInteger(modulus, 16), type: 'RSA' };
}
throw new Error("Unable to extract public key");
}
function extractModulus(publicKeyInfo: string): string | null {
// RSA OID
const rsaOid = '2a864886f70d010101';
// RSA-PSS OID
const rsaPssOid = '2a864886f70d01010a';
let offset = publicKeyInfo.indexOf(rsaOid);
if (offset === -1) {
offset = publicKeyInfo.indexOf(rsaPssOid);
}
if (offset === -1) {
return null;
}
// Skip OID and move to the bit string
offset = publicKeyInfo.indexOf('03', offset);
if (offset === -1) {
return null;
}
// Skip bit string tag and length
offset += 4;
// Extract modulus
const modulusStart = publicKeyInfo.indexOf('02', offset) + 2;
const modulusLength = parseInt(publicKeyInfo.substr(modulusStart, 2), 16) * 2;
const modulus = publicKeyInfo.substr(modulusStart + 2, modulusLength);
return modulus;
}
async function serialize_new_csca_modulus_tree_new() {
const tree = new IMT(poseidon2, CSCA_TREE_DEPTH, 0, 2);
const validAlgorithms = [
"SHA256withRSAandMGF1", // SHA1 with RSA
"SHA256withRSA", // SHA256 with RSA
"rsaPSS",
"SHA1withRSA" // RSA-PSS
];
const processCertificate = (certificate, filePath) => {
const signatureAlgorithm = certificate.getSignatureAlgorithmField();
if (!validAlgorithms.includes(signatureAlgorithm)) {
console.log(`Skipping file ${filePath}: Unsupported signature algorithm ${signatureAlgorithm}`);
return;
}
const publicKey = getPublicKey(certificate);
if (!isRsaPublicKey(publicKey)) {
console.log(`Skipping file ${filePath}: Not an RSA or RSA-PSS key`);
return;
}
const keyLength = publicKey.n.bitLength();
if (keyLength > 4096) {
console.log(`Skipping file ${filePath}: Key length ${keyLength} bits exceeds 4096 bits`);
return;
}
const modulus = publicKey.n.toString(16);
const modulus_bigint = BigInt(`0x${modulus}`);
let n_csca, k_csca;
console.log("keyLength: ", keyLength);
if (keyLength === 2048) {
n_csca = 64;
k_csca = 32;
}
else {
n_csca = 64;
k_csca = 64;
}
console.log(`File: ${filePath}`);
console.log(`Key Length: ${keyLength} bits`);
console.log(`Modulus: ${modulus}`);
console.log(`Key Type: ${publicKey.type}`);
console.log(`Signature Algorithm: ${signatureAlgorithm}`);
const finalPoseidonHash = computeLeafFromModulusBigInt(modulus_bigint);
console.log(`Final Poseidon Hash: ${finalPoseidonHash}`);
tree.insert(finalPoseidonHash.toString());
if (signatureAlgorithm === "1.2.840.113549.1.1.10") {
console.log(`RSA-PSS parameters not easily accessible with jsrsasign`);
}
console.log('---');
};
const path_to_pem_files = "outputs/unique_pem";
for (const file of fs.readdirSync(path_to_pem_files)) {
const file_path = path.join(path_to_pem_files, file);
const file_content = fs.readFileSync(file_path, 'utf8');
try {
const certificate = new jsrsasign.X509();
certificate.readCertPEM(file_content);
processCertificate(certificate, file_path);
} catch (error) {
console.error(`Error processing file ${file}:`, error);
}
}
if (DEVELOPMENT_MODE) {
const mockCscaList = [
'../common/src/mock_certificates/sha256_rsa_4096/mock_csca.crt',
'../common/src/mock_certificates/sha256_rsa_2048/mock_csca.crt',
'../common/src/mock_certificates/sha256_rsapss_4096/mock_csca.pem',
'../common/src/mock_certificates/sha256_rsapss_2048/mock_csca.pem',
'../common/src/mock_certificates/sha1_rsa_4096/mock_csca.crt',
'../common/src/mock_certificates/sha1_rsa_2048/mock_csca.crt'
];
for (const mockCscaFile of mockCscaList) {
try {
const certPem = fs.readFileSync(mockCscaFile, 'utf8');
const certificate = new jsrsasign.X509();
certificate.readCertPEM(certPem);
processCertificate(certificate, mockCscaFile);
} catch (error) {
console.error(`Error processing mock file ${mockCscaFile}:`, error);
}
}
}
const serializedTree = tree.nodes.map(layer => layer.map(node => node.toString()));
fs.writeFileSync("outputs/serialized_csca_tree.json", JSON.stringify(serializedTree));
fs.copyFileSync("outputs/serialized_csca_tree.json", "../common/pubkeys/serialized_csca_tree.json");
console.log("serialized_csca_tree.json written and copied in common/pubkeys!")
}
serialize_new_csca_modulus_tree_new();

View File

@@ -11,7 +11,7 @@ export interface StandardCurve {
export const standardCurves: StandardCurve[] = [
{
name: "secp256r1 (NIST P-256)",
name: "secp256r1",
p: "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
a: "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
b: "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
@@ -20,7 +20,7 @@ export const standardCurves: StandardCurve[] = [
h: "01"
},
{
name: "secp384r1 (NIST P-384)",
name: "secp384r1",
p: "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
a: "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
b: "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
@@ -29,7 +29,7 @@ export const standardCurves: StandardCurve[] = [
h: "01"
},
{
name: "secp521r1 (NIST P-521)",
name: "secp521r1",
p: "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
a: "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
b: "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",

View File

@@ -0,0 +1,58 @@
import * as fs from 'fs';
import * as path from 'path';
import { processCertificate, CertificateData, PublicKeyDetailsRSA, PublicKeyDetailsECDSA } from './utils';
export async function getMapJson(pemDirectory: string) {
try {
console.log(`\x1b[34mreading directory: ${pemDirectory}\x1b[0m`);
const files = fs.readdirSync(pemDirectory);
console.log(`\x1b[34mfound ${files.length} files\x1b[0m`);
const certificateMap: { [id: string]: { [issuer: string]: number } } = {};
for (const file of files) {
if (path.extname(file).toLowerCase() === '.pem') {
console.log(`\x1b[90mreading file: ${file}\x1b[0m`);
const pemFilePath = path.join(pemDirectory, file);
const pemContent = fs.readFileSync(pemFilePath, 'utf8');
const certificateData = processCertificate(pemContent, file);
if (certificateData) {
const mapKey = getMapKey(certificateData);
if (!certificateMap[mapKey]) {
certificateMap[mapKey] = {};
}
if (!certificateMap[mapKey][certificateData.issuer]) {
certificateMap[mapKey][certificateData.issuer] = 0;
}
certificateMap[mapKey][certificateData.issuer]++;
}
}
}
return certificateMap;
} catch (error) {
console.error('Error:', error);
}
}
function getMapKey(certificateData: CertificateData): string {
const { signatureAlgorithm, hashAlgorithm, publicKeyDetails } = certificateData;
let keyDetails = 'unknown';
if (publicKeyDetails) {
if (signatureAlgorithm === "ECDSA") {
// ECDSA
keyDetails = (publicKeyDetails as PublicKeyDetailsECDSA).curve;
} else {
// RSA
const keySize = ((publicKeyDetails as PublicKeyDetailsRSA).modulus.length * 4).toString();
const exponent = (publicKeyDetails as PublicKeyDetailsRSA).exponent;
keyDetails = `${keySize} bit ${exponent}`;
}
}
return `${hashAlgorithm.toLowerCase()} ${signatureAlgorithm.toLowerCase()} ${keyDetails}`;
}

View File

@@ -2,21 +2,18 @@ import * as fs from 'fs';
import * as path from 'path';
import { processCertificate } from './utils';
const pemDirectory = path.join(__dirname, '..', '..', 'outputs', 'unique_pem_masterlist');
async function main() {
export async function getRegistryJson(pemDirectory: string) {
try {
console.log('Database initialized');
console.log(`Reading directory: ${pemDirectory}`);
console.log(`\x1b[34mreading directory: ${pemDirectory}\x1b[0m`);
const files = fs.readdirSync(pemDirectory);
console.log(`Found ${files.length} files`);
console.log(`\x1b[34mfound ${files.length} files\x1b[0m`);
const certificateMap: { [id: string]: any } = {};
for (const file of files) {
if (path.extname(file).toLowerCase() === '.pem') {
console.log(`Processing file: ${file}`);
console.log(`\x1b[90mreading file: ${file}\x1b[0m`);
const pemFilePath = path.join(pemDirectory, file);
const pemContent = fs.readFileSync(pemFilePath, 'utf8');
const certificateData = processCertificate(pemContent, file);
@@ -26,15 +23,11 @@ async function main() {
}
}
console.log('Certificate Map:', JSON.stringify(certificateMap, null, 2));
// Optionally, you can write the map to a file
fs.writeFileSync('certificateMap.json', JSON.stringify(certificateMap, null, 2));
console.log('Certificate map has been written to certificateMap.json');
// fs.writeFileSync('certificateMap.json', JSON.stringify(certificateMap, null, 2));
// console.log('Certificate map has been written to certificateMap.json');
return certificateMap;
} catch (error) {
console.error('Error in main:', error);
console.error('Error:', error);
}
}
console.log('Script started');
main();

View File

@@ -0,0 +1,32 @@
import * as fs from 'fs';
import * as path from 'path';
import { processCertificate } from './utils';
export async function getSkiModulusJson(pemDirectory: string) {
try {
console.log(`\x1b[34mreading directory: ${pemDirectory}\x1b[0m`);
const files = fs.readdirSync(pemDirectory);
console.log(`\x1b[34mfound ${files.length} files\x1b[0m`);
const skiModulusMap: { [ski: string]: string } = {};
for (const file of files) {
if (path.extname(file).toLowerCase() === '.pem') {
console.log(`\x1b[90mreading file: ${file}\x1b[0m`);
const pemFilePath = path.join(pemDirectory, file);
const pemContent = fs.readFileSync(pemFilePath, 'utf8');
const certificateData = processCertificate(pemContent, file);
if (certificateData && certificateData.subjectKeyIdentifier && certificateData.publicKeyDetails) {
if ('modulus' in certificateData.publicKeyDetails) {
skiModulusMap[certificateData.subjectKeyIdentifier] = certificateData.publicKeyDetails.modulus;
}
}
}
}
return skiModulusMap;
} catch (error) {
console.error('Error:', error);
return {};
}
}

View File

@@ -55,7 +55,7 @@ export function parseECParameters(publicKeyInfo: any): PublicKeyDetailsECDSA {
const algorithmParams = publicKeyInfo.algorithm.algorithmParams;
if (!algorithmParams) {
console.log('No algorithm params found');
return { curve: 'Unknown', params: {} as StandardCurve };
return { curve: 'Unknown', params: {} as StandardCurve, bits: 'Unknown' };
}
const params = asn1.fromBER(algorithmParams.valueBeforeDecodeView).result;
@@ -100,25 +100,30 @@ export function parseECParameters(publicKeyInfo: any): PublicKeyDetailsECDSA {
}
const identifiedCurve = identifyCurve(curveParams);
return { curve: identifiedCurve, params: curveParams };
return { curve: identifiedCurve, params: curveParams, bits: getECDSACurveBits(identifiedCurve) };
} else {
if (valueBlock.value) {
console.log('value block length:', valueBlock.value.length);
if (algorithmParams.idBlock.tagNumber === 6) {
console.log('\x1b[33malgorithmParams.idBlock.tagNumber === 6, looking for algorithmParams.valueBlock\x1b[0m');
const curveOid = algorithmParams.valueBlock.toString();
const curveName = getNamedCurve(curveOid);
// console.log('Curve OID:', curveName);
return { curve: curveName, params: {} as StandardCurve };
// console.error('\x1b[33mCurve OID:', curveName, '\x1b[0m');
return { curve: curveName, params: {} as StandardCurve, bits: getECDSACurveBits(curveName) };
}
else {
console.log('\x1b[31malgorithmParams.idBlock.tagNumber !== 6\x1b[0m');
}
}
else {
console.log('value block is not defined');
console.error('\x1b[31mvalue block is not defined\x1b[0m');
}
return { curve: 'Unknown', params: {} as StandardCurve };
return { curve: 'Unknown', params: {} as StandardCurve, bits: 'Unknown' };
}
} catch (error) {
console.error('Error parsing EC parameters:', error);
return { curve: 'Error', params: {} as StandardCurve };
return { curve: 'Error', params: {} as StandardCurve, bits: 'Unknown' };
}
}
@@ -140,11 +145,13 @@ export interface CertificateData {
export interface PublicKeyDetailsRSA {
modulus: string;
exponent: string;
bits: string;
}
export interface PublicKeyDetailsECDSA {
curve: string;
params: StandardCurve;
bits: string;
}
export function processCertificate(pemContent: string, fileName: string): CertificateData {
@@ -216,14 +223,15 @@ export function processCertificate(pemContent: string, fileName: string): Certif
new forge.jsbn.BigInteger(modulusHex, 16),
new forge.jsbn.BigInteger(exponentHex, 16)
);
const PublicKeyDetailsRSA = {
const PublicKeyDetailsRSA: PublicKeyDetailsRSA = {
modulus: publicKeyForge.n.toString(16),
exponent: publicKeyForge.e.toString(10)
exponent: publicKeyForge.e.toString(10),
bits: publicKeyForge.n.bitLength().toString()
};
certificateData.publicKeyDetails = PublicKeyDetailsRSA;
}
else {
console.log('\x1b[90mRSA public key not found, probably ECDSA certificate\x1b[0m');
console.log('\x1b[33mRSA public key not found, probably ECDSA certificate\x1b[0m');
}
}
if (signatureAlgorithm === 'RSA-PSS') {
@@ -270,4 +278,25 @@ export function processCertificate(pemContent: string, fileName: string): Certif
} catch (error) {
console.error(`Error processing ${fileName}:`, error);
}
}
function getECDSACurveBits(curveName: string): string {
const curveBits: { [key: string]: number } = {
'secp256r1': 256,
'secp384r1': 384,
'secp521r1': 521,
'brainpoolP256r1': 256,
'brainpoolP384r1': 384,
'brainpoolP512r1': 512,
'secp256r1 (NIST P-256)': 256,
'secp384r1 (NIST P-384)': 384,
'secp521r1 (NIST P-521)': 521,
};
if (curveName in curveBits) {
return curveBits[curveName].toString();
}
console.log('\x1b[31m%s\x1b[0m', `curve name ${curveName} not found in curveBits`);
return "unknown";
}