Skip to content

Commit 5d3adae

Browse files
committed
add exploration of certificate signing request
1 parent 3fe3b58 commit 5d3adae

File tree

10 files changed

+3090
-112
lines changed

10 files changed

+3090
-112
lines changed

package-lock.json

Lines changed: 2933 additions & 101 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"makedoc": "npx typedoc -out doc",
1515
"cost-of-modules": "npx cost-of-modules --no-install",
1616
"release-it": "npx release-it",
17-
"prettier-format": "prettier --config .prettierrc.js lib/**/*.ts test/**/*.ts --write"
17+
"prettier-format": "prettier --config .prettierrc.js lib/**/*.ts test/**/*.ts --write",
18+
"ncu": "npx npm-check-updates -u"
1819
},
1920
"keywords": [
2021
"OPCUA",
@@ -28,13 +29,13 @@
2829
"license": "MIT",
2930
"devDependencies": {
3031
"@types/mocha": "^8.2.0",
31-
"@types/node": "^14.14.12",
32+
"@types/node": "^14.14.16",
3233
"@types/should": "^13.0.0",
33-
"@typescript-eslint/eslint-plugin": "^4.9.1",
34-
"@typescript-eslint/parser": "^4.9.1",
35-
"eslint": "^7.15.0",
36-
"eslint-config-prettier": "^7.0.0",
37-
"eslint-plugin-prettier": "^3.2.0",
34+
"@typescript-eslint/eslint-plugin": "^4.11.1",
35+
"@typescript-eslint/parser": "^4.11.1",
36+
"eslint": "^7.16.0",
37+
"eslint-config-prettier": "^7.1.0",
38+
"eslint-plugin-prettier": "^3.3.0",
3839
"lorem-ipsum": "^2.0.3",
3940
"mocha": "^8.2.1",
4041
"prettier": "^2.2.1",
@@ -43,8 +44,8 @@
4344
"source-map-support": "^0.5.19",
4445
"ts-node": "^9.1.1",
4546
"tslint": "^6.1.3",
46-
"typescript": "^4.1.3",
47-
"tslint-config-prettier": "^1.18.0"
47+
"tslint-config-prettier": "^1.18.0",
48+
"typescript": "^4.1.3"
4849
},
4950
"dependencies": {
5051
"better-assert": "^1.0.2",

source/crypto_explore_certificate.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ function readExtKeyUsage(oid: string, buffer: Buffer): string {
385385
-- by extnID
386386
}
387387
*/
388-
function _readExtension(buffer: Buffer, block: BlockInfo) {
388+
export function _readExtension(buffer: Buffer, block: BlockInfo) {
389389
const inner_blocks = _readStruct(buffer, block);
390390

391391
if (inner_blocks.length === 3) {
@@ -544,7 +544,7 @@ export interface TbsCertificate {
544544
extensions: CertificateExtension | null;
545545
}
546546

547-
function readTbsCertificate(buffer: Buffer, block: BlockInfo): TbsCertificate {
547+
export function readTbsCertificate(buffer: Buffer, block: BlockInfo): TbsCertificate {
548548
const blocks = _readStruct(buffer, block);
549549

550550
let version, serialNumber, signature, issuer, validity, subject, subjectFingerPrint, subjectPublicKeyInfo, extensions;
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import * as assert from "assert";
2+
import { BlockInfo, readTag, _findBlockAtIndex, _getBlock, _readObjectIdentifier, _readStruct, _readVersionValue } from "./asn1";
3+
4+
import { BasicConstraints, _readExtension } from "./crypto_explore_certificate";
5+
6+
export interface ExtensionRequest {
7+
basicConstraints: BasicConstraints,
8+
keyUsage: KeyUsage,
9+
subjectAltName: any
10+
}
11+
export interface CertificateSigningRequestInfo {
12+
extensionRequest: ExtensionRequest
13+
}
14+
15+
function _readExtensionRequest(buffer: Buffer): ExtensionRequest {
16+
const block = readTag(buffer, 0);
17+
18+
19+
const inner_blocks = _readStruct(buffer, block);
20+
const extensions = inner_blocks.map((block1) => _readExtension(buffer, block1));
21+
22+
const result: any = {};
23+
for (const e of extensions) {
24+
result[e.identifier.name] = e.value;
25+
}
26+
const { basicConstraints, keyUsage, subjectAltName } = result;
27+
return { basicConstraints, keyUsage, subjectAltName };
28+
}
29+
30+
export function readCertificationRequestInfo(buffer: Buffer, block: BlockInfo): CertificateSigningRequestInfo {
31+
const blocks = _readStruct(buffer, block);
32+
if (blocks.length === 4) {
33+
const extensionRequestBlock = _findBlockAtIndex(blocks, 0);
34+
if (!extensionRequestBlock) {
35+
throw new Error("cannot find extensionRequest block");
36+
}
37+
const blocks1 = _readStruct(buffer, extensionRequestBlock);
38+
const blocks2 = _readStruct(buffer, blocks1[0]);
39+
const identifier = _readObjectIdentifier(buffer, blocks2[0]);
40+
if (identifier.name !== "extensionRequest") {
41+
throw new Error(" Cannot find extension Request in ASN1 block");
42+
}
43+
const buf = _getBlock(buffer, blocks2[1]);
44+
45+
const extensionRequest = _readExtensionRequest(buf);
46+
47+
return { extensionRequest };
48+
}
49+
throw new Error("Invalid CSR or ");
50+
}
51+
52+
// see https://tools.ietf.org/html/rfc2986 : Certification Request Syntax Specification Version 1.7
53+
54+
export function exploreCertificateSigningRequest(crl: Buffer): CertificateSigningRequestInfo {
55+
const blockInfo = readTag(crl, 0);
56+
const blocks = _readStruct(crl, blockInfo);
57+
const csrInfo = readCertificationRequestInfo(crl, blocks[0]);
58+
return csrInfo;
59+
}

source/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ export * from "./crypto_utils";
88
export * from "./crypto_explore_certificate";
99
export * from "./verify_certificate_signature";
1010
export * from "./explore_certificate_revocation_list";
11+
export * from "./explore_certificate_signing_request";

source_nodejs/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from "./read";
22
export * from "./read_certificate_revocation_list";
3+
export * from "./read_certificate_signing_request";
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import * as fs from "fs";
2+
import { promisify } from "util";
3+
import { convertPEMtoDER } from "../source/crypto_utils";
4+
import { CertificateRevocationList } from "../source/common";
5+
import { assert } from "console";
6+
7+
export type CertificateSigningRequest = Buffer;
8+
9+
export async function readCertificateSigningRequest(filename: string): Promise<CertificateSigningRequest> {
10+
const csr = await promisify(fs.readFile)(filename);
11+
if (csr[0] === 0x30 && csr[1] === 0x82) {
12+
// der format
13+
return csr as CertificateRevocationList;
14+
}
15+
const raw_crl = csr.toString();
16+
return convertPEMtoDER(raw_crl);
17+
}

test/fixtures/csr/csr1.pem

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
-----BEGIN CERTIFICATE REQUEST-----
2+
MIIC8jCCAdoCAQAwTTELMAkGA1UEBhMCRlIxEDAOBgNVBAcMB09STEVBTlMxETAP
3+
BgNVBAoMCFN0ZXJmaXZlMRkwFwYDVQQDDBBGYWtlLU9QQ1VBU2VydmVyMIIBIjAN
4+
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuJrwfWy0ZAy4hXdtMFmoz4FY+31x
5+
7cKFSEW1YUrHnfsnmO/rlD7U3InQL6jhIXZQNgPQ+MGc/E/VEJ2d0EzX0Q0gNrcv
6+
RTXiXsjRaY5oyBK6BWHuiykb45kz7oY3h7hvnAlKbhlib2MeWCOSFLQDEB6zsWKY
7+
AR5rwA3mqzlBG2MlRs+Xj4zHegVXyPSnRF2fNcJWVrH11DD5rdxqEEnlRLPiTPgp
8+
QLJWealXGgMly35XyCQi+exGevBuwVXB1IEwupjJ3VBLwL4Qe7E4Bs8rVeYKMHCO
9+
Rireug/uaGcG3sY6aJ9irrWa2fnNoE64TOP0aXUp8civDxL2kQS8pt92BQIDAQAB
10+
oGAwXgYJKoZIhvcNAQkOMVEwTzAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIBBjAy
11+
BgNVHREEKzAphhZ1cm46U29tZS1GYWtlLVNlcnZlci0xgg9ERVNLVE9QLTZQMDc0
12+
TFIwDQYJKoZIhvcNAQELBQADggEBABj6lJ4v9hCektKk+d2T9lamV9J2MLSktEWe
13+
HL70fhYF6OeUzhfL0q6xRbBrCYpHt+UwXjYDJcbEUh3uh40sLXGeKXfnEbgwaZy4
14+
YOl1z1V3HmUg4V4GDhvYhj1Y5PkSzblnrBwqAGol3zWAlkgcHTLI8WJdrutz+lry
15+
BLubv3R8cHa158bWTnmnH0ThAlVOrELVuIMSZ86WZX2PQH09+v8Xg1Rgva6vOeLa
16+
DFqRVNcj/dXUjsyQM5XG30dZRfDnG4kBcML1fzCl2YLwLBrT+d6V0NR6BP0gkCs1
17+
3PshAiIJ0KCeE+iwml4V0th7Of+LF6c4pLvxDQrkd6gDpxy+DUk=
18+
-----END CERTIFICATE REQUEST-----

test/fixtures/csr/csr2.pem

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
-----BEGIN CERTIFICATE REQUEST-----
2+
MIIDEDCCAfgCAQAwTTELMAkGA1UEBhMCRlIxEDAOBgNVBAcMB09STEVBTlMxETAP
3+
BgNVBAoMCFN0ZXJmaXZlMRkwFwYDVQQDDBBGYWtlLU9QQ1VBU2VydmVyMIIBIjAN
4+
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuJrwfWy0ZAy4hXdtMFmoz4FY+31x
5+
7cKFSEW1YUrHnfsnmO/rlD7U3InQL6jhIXZQNgPQ+MGc/E/VEJ2d0EzX0Q0gNrcv
6+
RTXiXsjRaY5oyBK6BWHuiykb45kz7oY3h7hvnAlKbhlib2MeWCOSFLQDEB6zsWKY
7+
AR5rwA3mqzlBG2MlRs+Xj4zHegVXyPSnRF2fNcJWVrH11DD5rdxqEEnlRLPiTPgp
8+
QLJWealXGgMly35XyCQi+exGevBuwVXB1IEwupjJ3VBLwL4Qe7E4Bs8rVeYKMHCO
9+
Rireug/uaGcG3sY6aJ9irrWa2fnNoE64TOP0aXUp8civDxL2kQS8pt92BQIDAQAB
10+
oH4wfAYJKoZIhvcNAQkOMW8wbTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIBBjBQ
11+
BgNVHREESTBHhhZ1cm46U29tZS1GYWtlLVNlcnZlci0xgg9ERVNLVE9QLTZQMDc0
12+
TFKHBKweoAGHBKwbAAGHBMCoARKHBKwX8AGHBKwbgAEwDQYJKoZIhvcNAQELBQAD
13+
ggEBAE+yxWv79IQrKC1INF2QerxvKXm0IrrEG6P2kBnEZpmOS4yTKpIZfxg0zYM5
14+
ocfBrzc9/XqrZNb1pkd9NHauAhtFrAMPd2oF6uslVWs4sINjk0Vi4ADD+uO/QqXb
15+
JR2GedevxInLvmmF4c3ZoA0uZPzdcWkUwwF/sn3RLhnTlsN6oTbDi0gsrr/w+3tN
16+
0kmQVpKr6Cg8au4tSYotyf3m4f9qqiECHvdNdwFLqDiVLwioye2l/3RlAjeNQOiX
17+
wIUH9H8VfzLiIzJ0lJ7MGzSua9plD5zWK6HrdvKFSVuzT/abgF2cy6dkIgrxSNMT
18+
zv8Y7pNs/PuPusN5ZHypZ3N3dc8=
19+
-----END CERTIFICATE REQUEST-----

test/test_explore_csr.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import * as path from "path";
2+
import { exploreCertificateSigningRequest } from "../source/explore_certificate_signing_request";
3+
4+
import { readCertificateSigningRequest } from "../source_nodejs";
5+
6+
const doDebug = !!process.env.DEBUG;
7+
8+
9+
describe("Explore Certificate Signing Request", () => {
10+
it("ECSR1- should read and explore a Certificate Signing Request", async () => {
11+
const csr1Filename = path.join(__dirname, "fixtures/csr/csr1.pem");
12+
const csr1 = await readCertificateSigningRequest(csr1Filename);
13+
14+
const csrInfo = exploreCertificateSigningRequest(csr1);
15+
16+
csrInfo.extensionRequest.subjectAltName.should.eql({
17+
uniformResourceIdentifier: [
18+
"urn:Some-Fake-Server-1"
19+
],
20+
dNSName: [
21+
"DESKTOP-6P074LR"
22+
]
23+
});
24+
25+
if (doDebug) {
26+
console.log(JSON.stringify(csrInfo,null, " "));
27+
}
28+
});
29+
30+
});

0 commit comments

Comments
 (0)