-
Notifications
You must be signed in to change notification settings - Fork 87
/
common.ts
151 lines (130 loc) · 4.47 KB
/
common.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import { NoCryptoEngineError } from '@quiet/types'
import { fromBER, type ObjectIdentifier } from 'asn1js'
import {
getAlgorithmParameters,
getCrypto,
CertificationRequest,
Certificate,
TSTInfo,
ECNamedCurves,
type AttributeTypeAndValue,
} from 'pkijs'
import { stringToArrayBuffer, fromBase64 } from 'pvutils'
export enum CertFieldsTypes {
commonName = '2.5.4.3',
subjectAltName = '2.5.29.17',
nickName = '1.3.6.1.4.1.50715.2.1',
peerId = '1.3.6.1.2.1.15.3.1.1',
dmPublicKey = '1.2.840.113549.1.9.12',
}
export enum ExtensionsTypes {
basicConstr = '2.5.29.19',
keyUsage = '2.5.29.15',
extKeyUsage = '2.5.29.37',
}
export function hexStringToArrayBuffer(str: string): ArrayBuffer {
const stringLength = str.length / 2
const resultBuffer = new ArrayBuffer(stringLength)
const resultView = new Uint8Array(resultBuffer)
// noinspection NonBlockStatementBodyJS
for (let i = 0; i < stringLength; i++) {
resultView[i] = parseInt(str.slice(i * 2, i * 2 + 2), 16)
}
return resultBuffer
}
export function arrayBufferToHexString(buffer: Buffer): string {
let resultString = ''
const view = new Uint8Array(buffer)
// noinspection NonBlockStatementBodyJS
for (const element of view) {
resultString += element.toString(16).padStart(2, '0')
}
return resultString
}
export const generateKeyPair = async ({ signAlg }: { signAlg: string }): Promise<CryptoKeyPair> => {
const algorithm = getAlgorithmParameters(signAlg, 'generateKey')
const crypto = getCrypto()
if (!crypto) throw new NoCryptoEngineError()
const keyPair = await crypto.generateKey(algorithm.algorithm as EcKeyGenParams, true, algorithm.usages)
return keyPair
}
export const formatPEM = (pemString: string): string => {
const stringLength = pemString.length
let resultString = ''
for (let i = 0, count = 0; i < stringLength; i++, count++) {
if (count > 63) {
resultString = `${resultString}\n`
count = 0
}
resultString = `${resultString}${pemString[i]}`
}
return resultString
}
export const loadCertificate = (rootCert: string): Certificate => {
const certificateBuffer = stringToArrayBuffer(fromBase64(rootCert))
const asn1 = fromBER(certificateBuffer)
return new Certificate({ schema: asn1.result })
}
export const loadPrivateKey = async (rootKey: string, signAlg: string): Promise<CryptoKey> => {
const keyBuffer = stringToArrayBuffer(fromBase64(rootKey))
const algorithm = getAlgorithmParameters(signAlg, 'generateKey')
const crypto = getCrypto()
if (!crypto) throw new NoCryptoEngineError()
return await crypto.importKey('pkcs8', keyBuffer, algorithm.algorithm as Algorithm, true, algorithm.usages)
}
export const loadCSR = async (csr: string): Promise<CertificationRequest> => {
const certBuffer = stringToArrayBuffer(fromBase64(csr))
const asn1 = fromBER(certBuffer)
return new CertificationRequest({ schema: asn1.result })
}
export const getCertFieldValue = (cert: Certificate, fieldType: CertFieldsTypes | ObjectIdentifier): string | null => {
if (fieldType === CertFieldsTypes.commonName) {
const block = cert.subject.typesAndValues.find((tav: AttributeTypeAndValue) => tav.type === fieldType)
if (block) {
return block?.value.valueBlock.value
} else {
return null
}
} else {
const ext = cert.extensions?.find(tav => tav.extnID === fieldType)
if (ext) {
if (fieldType === CertFieldsTypes.dmPublicKey) {
const extObj = ext?.extnValue.valueBlock.value[0]
// @ts-ignore
const arrayBuffer = extObj.valueBlock.valueHex
return arrayBufferToHexString(arrayBuffer)
} else {
const extObj = ext?.extnValue.valueBlock.value[0]
// @ts-ignore
return extObj.valueBlock.value
}
} else {
return null
}
}
}
export const getReqFieldValue = (
csr: CertificationRequest,
fieldType: CertFieldsTypes | ObjectIdentifier
): string | null => {
if (fieldType === CertFieldsTypes.commonName) {
const block = csr.subject.typesAndValues.find((tav: AttributeTypeAndValue) => tav.type === fieldType)
if (block) {
return block?.value.valueBlock.value
} else {
return null
}
} else {
const ext = csr.attributes?.find(tav => tav.type === fieldType)
if (ext) {
if (fieldType === CertFieldsTypes.dmPublicKey) {
const extObj = ext.values[0].valueBlock.valueHex
return arrayBufferToHexString(extObj)
} else {
return ext.values[0].valueBlock.value
}
} else {
return null
}
}
}