WIP more asn1

This commit is contained in:
AJ ONeal 2018-11-18 14:34:20 -07:00
parent ba92407194
commit ab8ec9fa7c
1 changed files with 55 additions and 52 deletions

View File

@ -26,21 +26,21 @@ function ASN1() {
}
return hex + numToHex(len) + str;
}
function UINT() {
ASN1.UInt = function UINT() {
var str = Array.prototype.slice.call(arguments).join('');
var first = parseInt(str.slice(0, 2), 16);
// high-order bit means signed, negative
// we want positive, so we pad with a leading '00'
if (0x80 & first) { str = '00' + str; }
return ASN1('02', str);
}
};
function BITSTR() {
ASN1.BitStr = function BITSTR() {
var str = Array.prototype.slice.call(arguments).join('');
// '00' is a mask of how many bits of the next byte to ignore
return ASN1('03', '00' + str);
}
};
function SEQ() {
return ASN1('30', Array.prototype.slice.call(arguments).join(''));
}
@ -204,22 +204,27 @@ function csrEcSig(r, s) {
// (ANSI X9.62 ECDSA algorithm with SHA256)
OBJID('2A 86 48 CE 3D 04 03 02')
)
, BITSTR(
, ASN1.BitStr(
SEQ(
UINT(toHex(r))
, UINT(toHex(s))
ASN1.UInt(toHex(r))
, ASN1.UInt(toHex(s))
)
)
].join('');
}
var csrDomains = '82 {dlen} {domain.tld}'; // 2+n bytes (type 82?)
// TODO utf8
function strToHex(str) {
return str.split('').map(function (ch) {
var h = ch.charCodeAt(0).toString(16);
if (2 === h.length) {
return h;
}
var escstr = encodeURIComponent(str);
// replaces any uri escape sequence, such as %0A,
// with binary escape, such as 0x0A
var binstr = escstr.replace(/%([0-9A-F]{2})/g, function(match, p1) {
return String.fromCharCode('0x' + p1);
});
return binstr.split('').map(function (b) {
var h = b.charCodeAt(0).toString(16);
if (2 === h.length) { return h; }
return '0' + h;
}).join('');
}
@ -249,7 +254,7 @@ function fromHex(hex) {
function createCsrBodyEc(domains, xy) {
var altnames = domains.map(function (d) {
return csrDomains.replace(/{dlen}/, numToHex(d.length)).replace(/{domain\.tld}/, strToHex(d));
return ASN1('82', strToHex(d));
}).join('').replace(/\s+/g, '');
var sublen = domains[0].length;
var sanlen = (altnames.length/2);
@ -272,56 +277,54 @@ function createCsrBodyEc(domains, xy) {
hxy += toHex(xy.y);
}
var version = ASN1.UInt('00');
var subject = ASN1('30'
, ASN1('31'
, ASN1('30'
// object id (commonName)
, ASN1('06', '55 04 03')
, ASN1('0C', strToHex(domains[0])))));
var pubkey = ASN1('30'
, ASN1('30'
// 1.2.840.10045.2.1 ecPublicKey
// (ANSI X9.62 public key type)
, ASN1('06', '2A 86 48 CE 3D 02 01')
// 1.2.840.10045.3.1.7 prime256v1
// (ANSI X9.62 named elliptic curve)
, ASN1('06', '2A 86 48 CE 3D 03 01 07')
)
, ASN1.BitStr(compression + hxy));
var altnames = ASN1('A0'
, ASN1('30'
// (extensionRequest (PKCS #9 via CRMF))
, ASN1('06', '2A 86 48 86 F7 0D 01 09 0E')
, ASN1('31'
, ASN1('30'
, ASN1('30'
// (subjectAltName (X.509 extension))
, ASN1('06', '55 1D 11')
, ASN1('04'
, ASN1('30', domains.map(function (d) {
return csrDomains.replace(/{dlen}/, numToHex(d.length)).replace(/{domain\.tld}/, strToHex(d));
}).join(''))))))));
var body = [ '30 81 {+85+n}' // 4 bytes, sequence
.replace(/{[^}]+}/, numToHex(
3
+ 13 + sublen
+ 27 + publen // Length for EC-related P-256 stuff
+ 30 + sanlen
))
.replace(/{[^}]+}/, numToHex(3 + 13 + sublen + 27 + publen + 30 + sanlen))
// #0 Total 3
, ASN1('02', '00')
, version
// Subject
// #1 Total 2+11+n
, ASN1('30'
, ASN1('31'
, ASN1('30'
// object id (commonName)
, ASN1('06', '55 04 03')
, ASN1('0C', strToHex(domains[0]))
)
)
)
, subject
// P-256 Public Key
// #2 Total 2+25+xy
, ASN1('30'
, ASN1('30'
// 1.2.840.10045.2.1 ecPublicKey
// (ANSI X9.62 public key type)
, ASN1('06', '2A 86 48 CE 3D 02 01')
// 1.2.840.10045.3.1.7 prime256v1
// (ANSI X9.62 named elliptic curve)
, ASN1('06', '2A 86 48 CE 3D 03 01 07')
)
, BITSTR(compression + hxy)
)
, pubkey
// Altnames
// #3 Total 2+28+n
, ASN1('A0'
, ASN1('30'
// (extensionRequest (PKCS #9 via CRMF))
, ASN1('06', '2A 86 48 86 F7 0D 01 09 0E')
, ASN1('31'
, ASN1('30'
, ASN1('30'
// (subjectAltName (X.509 extension))
, ASN1('06', '55 1D 11')
, ASN1('04'
, ASN1('30', altnames))))))) ];
, altnames
];
body = body.join('').replace(/\s+/g, '');
return fromHex(body);
}