• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2const asn1 = require('asn1.js');
3const crypto = require('crypto');
4const fs = require('fs');
5const rfc5280 = require('asn1.js-rfc5280');
6const BN = asn1.bignum;
7
8const id_at_commonName = [ 2, 5, 4, 3 ];
9const rsaEncryption = [1, 2, 840, 113549, 1, 1, 1];
10const sha256WithRSAEncryption = [1, 2, 840, 113549, 1, 1, 11];
11const digest = 'SHA256';
12
13const private_key = fs.readFileSync('./0-dns-key.pem');
14// public key file can be generated from the private key with
15// openssl rsa -in 0-dns-key.pem -RSAPublicKey_out -outform der
16// -out 0-dns-rsapub.der
17const public_key = fs.readFileSync('./0-dns-rsapub.der');
18
19const now = Date.now();
20const days = 3650;
21
22const Null_ = asn1.define('Null_', function() {
23  this.null_();
24});
25const null_ = Null_.encode('der');
26
27const PrintStr = asn1.define('PrintStr', function() {
28  this.printstr();
29});
30const issuer = PrintStr.encode('ca.example.com', 'der');
31const subject = PrintStr.encode('evil.example.com', 'der');
32
33const tbs = {
34  version: 'v3',
35  serialNumber: new BN('01', 16),
36  signature: { algorithm: sha256WithRSAEncryption, parameters: null_},
37  issuer: { type: 'rdnSequence',
38            value: [ [{type: id_at_commonName, value: issuer}] ] },
39  validity:
40  { notBefore: { type: 'utcTime', value: now },
41    notAfter: { type: 'utcTime', value: now + days * 86400000} },
42  subject: { type: 'rdnSequence',
43             value: [ [{type: id_at_commonName, value: subject}] ] },
44  subjectPublicKeyInfo:
45  { algorithm: { algorithm: rsaEncryption, parameters: null_},
46    subjectPublicKey: { unused: 0, data: public_key} },
47  extensions:
48  [ { extnID: 'subjectAlternativeName',
49      critical: false,
50      // subjectAltName which contains '\0' character to check CVE-2009-2408
51      extnValue: [
52        { type: 'dNSName', value: 'good.example.org\u0000.evil.example.com' },
53        { type: 'dNSName', value: 'just-another.example.com' },
54        { type: 'iPAddress', value: Buffer.from('08080808', 'hex') },
55        { type: 'iPAddress', value: Buffer.from('08080404', 'hex') },
56        { type: 'dNSName', value: 'last.example.com' } ] }
57  ]
58};
59
60const tbs_der = rfc5280.TBSCertificate.encode(tbs, 'der');
61
62const sign = crypto.createSign(digest);
63sign.update(tbs_der);
64const signature = sign.sign(private_key);
65
66const cert = {
67  tbsCertificate: tbs,
68  signatureAlgorithm: { algorithm: sha256WithRSAEncryption, parameters: null_ },
69  signature:
70  { unused: 0,
71    data: signature }
72};
73const pem = rfc5280.Certificate.encode(cert, 'pem', {label: 'CERTIFICATE'});
74
75fs.writeFileSync('./0-dns-cert.pem', pem + '\n');
76