v0.0.2: WIP, useful as an example
This commit is contained in:
		
							parent
							
								
									ab5e1a0ee8
								
							
						
					
					
						commit
						30e617ada1
					
				@ -1,6 +1,9 @@
 | 
				
			|||||||
This is being ported from code from rsa-compat.js, greenlock.html (bacme.js), and others.
 | 
					This is being ported from code from rsa-compat.js, greenlock.html (bacme.js), and others.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Today is 2018-10-10 come back in a week.
 | 
					This is my project for the weekend. I expect to be finished today (Monday Nov 12th, 2018)
 | 
				
			||||||
 | 
					* 2018-10-10 (Saturday) work has begun
 | 
				
			||||||
 | 
					* 2018-10-11 (Sunday) W00T! got a CSR generated for RSA with VanillaJS ArrayBuffer
 | 
				
			||||||
 | 
					* 2018-10-12 (Monday) Figuring out ECDSA CSRs right now
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!--
 | 
					<!--
 | 
				
			||||||
Keypairs™ for node.js
 | 
					Keypairs™ for node.js
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										16
									
								
								convert-to-der.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								convert-to-der.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var fs = require('fs');
 | 
				
			||||||
 | 
					var path = require('path');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function convert(name) {
 | 
				
			||||||
 | 
					  var ext = path.extname(name);
 | 
				
			||||||
 | 
					  var csr = fs.readFileSync(name, 'ascii').split(/\n/).filter(function (line) {
 | 
				
			||||||
 | 
					    return !/---/.test(line);
 | 
				
			||||||
 | 
					  }).join('');
 | 
				
			||||||
 | 
					  console.log(csr);
 | 
				
			||||||
 | 
					  var der = Buffer.from(csr, 'base64');
 | 
				
			||||||
 | 
					  fs.writeFileSync(name.replace(new RegExp('\\' + ext + '$'), '') + '.der', der);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					convert(process.argv[2]);
 | 
				
			||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "keypairs",
 | 
					  "name": "keypairs",
 | 
				
			||||||
  "version": "0.0.1",
 | 
					  "version": "0.0.2",
 | 
				
			||||||
  "description": "Interchangeably use RSA & ECDSA with PEM and JWK for Signing, Verifying, CSR generation and JOSE. Ugh... that was a mouthful.",
 | 
					  "description": "Interchangeably use RSA & ECDSA with PEM and JWK for Signing, Verifying, CSR generation and JOSE. Ugh... that was a mouthful.",
 | 
				
			||||||
  "main": "index.js",
 | 
					  "main": "index.js",
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										23
									
								
								pubkey-cli.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								pubkey-cli.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var pubkey = require('./pubkey.js');
 | 
				
			||||||
 | 
					var pubname = process.argv[2];
 | 
				
			||||||
 | 
					var fs = require('fs');
 | 
				
			||||||
 | 
					var pem = fs.readFileSync(pubname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var key = pubkey.parsePem(pem);
 | 
				
			||||||
 | 
					if ('RSA' !== key.typ) {
 | 
				
			||||||
 | 
					  throw new Error(key.typ + " not supported");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					if (key.pub) {
 | 
				
			||||||
 | 
					  var pubbuf = pubkey.readPubkey(key.der);
 | 
				
			||||||
 | 
					} else {
 | 
				
			||||||
 | 
					  var pubbuf = pubkey.readPrivkey(key.der);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					console.log(pubbuf.byteLength, pubkey.toHex(pubbuf));
 | 
				
			||||||
 | 
					var der = pubkey.toRsaPub(pubbuf);
 | 
				
			||||||
 | 
					var b64 = pubkey.toBase64(der);
 | 
				
			||||||
 | 
					var pem = pubkey.formatAsPublicPem(b64);
 | 
				
			||||||
 | 
					console.log('Pub:\n');
 | 
				
			||||||
 | 
					console.log(pem);
 | 
				
			||||||
							
								
								
									
										181
									
								
								pubkey.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								pubkey.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,181 @@
 | 
				
			|||||||
 | 
					(function (exports) {
 | 
				
			||||||
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 30 sequence
 | 
				
			||||||
 | 
					// 03 bit string
 | 
				
			||||||
 | 
					// 05 null
 | 
				
			||||||
 | 
					// 06 object id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//       00                                                         00              00          00
 | 
				
			||||||
 | 
					// 30 82 01 22 30 0D 06 09  2A 86 48 86 F7 0D 01 01  01 05 00 03 82 01 0F 00  30 82 01 0A 02 82 01 01
 | 
				
			||||||
 | 
					// 00 ... 02 03 01 00 01
 | 
				
			||||||
 | 
					// 30 82 02 22 30 0D 06 09  2A 86 48 86 F7 0D 01 01  01 05 00 03 82 02 0F 00  30 82 02 0A 02 82 02 01
 | 
				
			||||||
 | 
					// 00 ... 02 03 01 00 01
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function parsePem(pem) {
 | 
				
			||||||
 | 
					  var typ;
 | 
				
			||||||
 | 
					  var pub;
 | 
				
			||||||
 | 
					  var der = fromBase64(pem.toString('ascii').split(/\n/).filter(function (line, i) {
 | 
				
			||||||
 | 
					    if (0 === i) {
 | 
				
			||||||
 | 
					      if (/ PUBLIC /.test(line)) {
 | 
				
			||||||
 | 
					        pub = true;
 | 
				
			||||||
 | 
					      } else if (/ PRIVATE /.test(line)) {
 | 
				
			||||||
 | 
					        pub = false;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (/ RSA /.test(line)) {
 | 
				
			||||||
 | 
					        typ = 'RSA';
 | 
				
			||||||
 | 
					      } else if (/ EC/.test(line)) {
 | 
				
			||||||
 | 
					        typ = 'EC';
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return !/---/.test(line);
 | 
				
			||||||
 | 
					  }).join(''));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!typ) {
 | 
				
			||||||
 | 
					    if (pub) {
 | 
				
			||||||
 | 
					      // This is the RSA object ID
 | 
				
			||||||
 | 
					      if ('06092A864886F70D010101'.toLowerCase() === der.slice(6, 6 + 11).toString('hex')) {
 | 
				
			||||||
 | 
					        typ = 'RSA';
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      // TODO
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return { typ: typ, pub: pub, der: der };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function toHex(ab) {
 | 
				
			||||||
 | 
					  var hex = [];
 | 
				
			||||||
 | 
					  var u8 = new Uint8Array(ab);
 | 
				
			||||||
 | 
					  var size = u8.byteLength;
 | 
				
			||||||
 | 
					  var i;
 | 
				
			||||||
 | 
					  var h;
 | 
				
			||||||
 | 
					  for (i = 0; i < size; i += 1) {
 | 
				
			||||||
 | 
					    h = u8[i].toString(16);
 | 
				
			||||||
 | 
					    if (2 === h.length) {
 | 
				
			||||||
 | 
					      hex.push(h);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      hex.push('0' + h);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return hex.join('');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function readPubkey(der) {
 | 
				
			||||||
 | 
					  var offset = 28 + 5; // header plus size
 | 
				
			||||||
 | 
					  var ksBytes = der.slice(30, 32);
 | 
				
			||||||
 | 
					  // not sure why it shows 257 instead of 256
 | 
				
			||||||
 | 
					  var keysize = new DataView(ksBytes).getUint16(0, false) - 1;
 | 
				
			||||||
 | 
					  var pub = der.slice(offset, offset + keysize);
 | 
				
			||||||
 | 
					  return pub;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function readPrivkey(der) {
 | 
				
			||||||
 | 
					  var offset = 7 + 5; // header plus size
 | 
				
			||||||
 | 
					  var ksBytes = der.slice(9, 11);
 | 
				
			||||||
 | 
					  // not sure why it shows 257 instead of 256
 | 
				
			||||||
 | 
					  var keysize = new DataView(ksBytes).getUint16(0, false) - 1;
 | 
				
			||||||
 | 
					  var pub = der.slice(offset, offset + keysize);
 | 
				
			||||||
 | 
					  return pub;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// I used OpenSSL to create RSA keys with sizes 2048 and 4096.
 | 
				
			||||||
 | 
					// Then I used https://lapo.it/asn1js/ to see which bits changed.
 | 
				
			||||||
 | 
					// And I created a template from the bits that do and don't.
 | 
				
			||||||
 | 
					// No ASN.1 and X.509 parsers or generators. Yay!
 | 
				
			||||||
 | 
					var rsaAsn1Head = (
 | 
				
			||||||
 | 
					    '30 82 xx 22 30 0D 06 09'
 | 
				
			||||||
 | 
					  + '2A 86 48 86 F7 0D 01 01'
 | 
				
			||||||
 | 
					  + '01 05 00 03 82 xx 0F 00'
 | 
				
			||||||
 | 
					  + '30 82 xx 0A 02 82 xx 01'
 | 
				
			||||||
 | 
					  + '00').replace(/\s+/g, '');
 | 
				
			||||||
 | 
					var rsaAsn1Foot = ('02 03 01 00 01').replace(/\s+/g, '');
 | 
				
			||||||
 | 
					function toRsaPub(pub) {
 | 
				
			||||||
 | 
					  // 256 // 2048-bit
 | 
				
			||||||
 | 
					  var len = '0' + (pub.byteLength / 256);
 | 
				
			||||||
 | 
					  var head = rsaAsn1Head.replace(/xx/g, len);
 | 
				
			||||||
 | 
					  var headSize = (rsaAsn1Head.length / 2);
 | 
				
			||||||
 | 
					  var foot = rsaAsn1Foot;
 | 
				
			||||||
 | 
					  var footSize = (foot.length / 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var size = headSize + pub.byteLength + footSize;
 | 
				
			||||||
 | 
					  var der = new Uint8Array(new ArrayBuffer(size));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var i, j;
 | 
				
			||||||
 | 
					  for (i = 0, j = 0; i < headSize; i += 1) {
 | 
				
			||||||
 | 
					    der[i] = parseInt(head.slice(j,j+2), 16);
 | 
				
			||||||
 | 
					    j += 2;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pub = new Uint8Array(pub);
 | 
				
			||||||
 | 
					  for (i = 0; i < pub.byteLength; i += 1) {
 | 
				
			||||||
 | 
					    der[headSize + i] = pub[i];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (i = 0, j = 0; i < footSize; i += 1) {
 | 
				
			||||||
 | 
					    der[headSize + pub.byteLength + i] = parseInt(foot.slice(j,j+2), 16);
 | 
				
			||||||
 | 
					    j += 2;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return der.buffer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function formatAsPem(str, privacy, pemName) {
 | 
				
			||||||
 | 
					  var pemstr = (pemName ? pemName + ' ' : '');
 | 
				
			||||||
 | 
					  var privstr = (privacy ? privacy + ' ' : '');
 | 
				
			||||||
 | 
					  var finalString = '-----BEGIN ' + pemstr + privstr + 'KEY-----\n';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  while (str.length > 0) {
 | 
				
			||||||
 | 
					      finalString += str.substring(0, 64) + '\n';
 | 
				
			||||||
 | 
					      str = str.substring(64);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  finalString = finalString + '-----END ' + pemstr + privstr + 'KEY-----';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return finalString;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function formatAsPublicPem(str) {
 | 
				
			||||||
 | 
					  return formatAsPem(str, 'PUBLIC', '');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function toBase64(der) {
 | 
				
			||||||
 | 
					  if ('undefined' === typeof btoa) {
 | 
				
			||||||
 | 
					    return Buffer.from(der).toString('base64');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
						var chs = [];
 | 
				
			||||||
 | 
						der = new Uint8Array(der);
 | 
				
			||||||
 | 
						der.forEach(function (b) {
 | 
				
			||||||
 | 
							chs.push(String.fromCharCode(b));
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					  return btoa(chs.join(''));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function fromBase64(b64) {
 | 
				
			||||||
 | 
					  var buf;
 | 
				
			||||||
 | 
					  var ab;
 | 
				
			||||||
 | 
					  if ('undefined' === typeof atob) {
 | 
				
			||||||
 | 
					    buf = Buffer.from(b64, 'base64');
 | 
				
			||||||
 | 
					    return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  buf = atob(b64);
 | 
				
			||||||
 | 
					  ab = new ArrayBuffer(buf.length);
 | 
				
			||||||
 | 
					  ab = new Uint8Array(ab);
 | 
				
			||||||
 | 
					  buf.split('').forEach(function (ch, i) {
 | 
				
			||||||
 | 
					    ab[i] = ch.charCodeAt(0);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  return ab.buffer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					exports.parsePem = parsePem;
 | 
				
			||||||
 | 
					exports.toBase64 = toBase64;
 | 
				
			||||||
 | 
					exports.toRsaPub = toRsaPub;
 | 
				
			||||||
 | 
					exports.formatAsPublicPem = formatAsPublicPem;
 | 
				
			||||||
 | 
					exports.formatAsPem = formatAsPem;
 | 
				
			||||||
 | 
					exports.readPubkey = readPubkey;
 | 
				
			||||||
 | 
					exports.readPrivkey = readPrivkey;
 | 
				
			||||||
 | 
					exports.toHex = toHex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}('undefined' !== typeof module ? module.exports: window));
 | 
				
			||||||
							
								
								
									
										404
									
								
								re-sign.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										404
									
								
								re-sign.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,404 @@
 | 
				
			|||||||
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var crypto = require('crypto');
 | 
				
			||||||
 | 
					var fs = require('fs');
 | 
				
			||||||
 | 
					var pubkey = require('./pubkey.js');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var keyname = process.argv[2];
 | 
				
			||||||
 | 
					var dername = process.argv[3];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var keypem = fs.readFileSync(keyname);
 | 
				
			||||||
 | 
					var csrFull = fs.readFileSync(dername);
 | 
				
			||||||
 | 
					var csrFull = csrFull.buffer.slice(csrFull.byteOffset, csrFull.byteOffset + csrFull.byteLength);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// these are static ASN.1 segments
 | 
				
			||||||
 | 
					// The head specifies that there will be 3 segments and a content length
 | 
				
			||||||
 | 
					// (those segments will be content, signature header, and signature)
 | 
				
			||||||
 | 
					var csrHead = '30 82 {0seq0len}'.replace(/\s+/g, '');
 | 
				
			||||||
 | 
					// The tail specifies the RSA256 signature header (and is followed by the signature
 | 
				
			||||||
 | 
					var csrRsaFoot =
 | 
				
			||||||
 | 
					  ( '30 0D 06 09 2A 86 48 86 F7 0D 01 01 0B'
 | 
				
			||||||
 | 
					  + '05 00'
 | 
				
			||||||
 | 
					  + '03 82 01 01 00'
 | 
				
			||||||
 | 
					  ).replace(/\s+/g, '');
 | 
				
			||||||
 | 
					var csrDomains = '82 {dlen} {domain.tld}';  // 2+n bytes (type 82?)
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					var csrRsaContent =
 | 
				
			||||||
 | 
					  '30 82 {1.1.0seqlen}'                     // 7+n    4 bytes, sequence
 | 
				
			||||||
 | 
					  + '02 01 00'                              // 3      3 bytes, int 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  + '30 {3.2.0seqlen}'                      // 13+n   2 bytes, sequence
 | 
				
			||||||
 | 
					    + '31 {4.3.0setlen}'                    // 11+n   2 bytes, set
 | 
				
			||||||
 | 
					      + '30 {5.4.0seqlen}'                  // 9+n    2 bytes, sequence
 | 
				
			||||||
 | 
					      + '06 03 55 04 03'                    // 7+n    5 bytes, object id (commonName)
 | 
				
			||||||
 | 
					      + '0C {dlen} {domain.tld}'            // 2+n    2+n bytes, utf8string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  + '30 82 {8.2.2seqlen}'                   // 19     4 bytes, sequence
 | 
				
			||||||
 | 
					    + '30 0D'                               // 15     2 bytes, sequence
 | 
				
			||||||
 | 
					      + '06 09 2A 86 48 86 F7 0D 01 01 01'  // 13     11 bytes, rsaEncryption (PKCS #1)
 | 
				
			||||||
 | 
					      + '05 00'                             // 2      2 bytes, null (why?)
 | 
				
			||||||
 | 
					    + '03 82 {12.3.0bslen} 00'              // +18+m  5 bytes, bit string [01 0F]
 | 
				
			||||||
 | 
					      + '30 82 {13.4.0seqlen}'              // +13+m  4 bytes, sequence
 | 
				
			||||||
 | 
					      + '02 82 {klen} 00 {key}'             // +9+m   4+1+n bytes, int (RSA Pub Key)
 | 
				
			||||||
 | 
					      + '02 03 {mod}'                       // +5     5 bytes, key and modules [01 00 01]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  + 'A0 {16.2.3ellen}'                      // 30+n   2 bytes, ?? [4B]
 | 
				
			||||||
 | 
					    + '30 {17.3.9seqlen}'                   // 28+n   2 bytes, sequence
 | 
				
			||||||
 | 
					      + '06 09 2A 86 48 86 F7 0D 01 09 0E'  // 26+n   11 bytes, object id (extensionRequest (PKCS #9 via CRMF))
 | 
				
			||||||
 | 
					        + '31 {19.5.0setlen}'               // 15+n   2 bytes, set
 | 
				
			||||||
 | 
					          + '30 {20.6.0seqlen}'             // 13+n   2 bytes, sequence
 | 
				
			||||||
 | 
					            + '30 {21.7.0seqlen}'           // 11+n   2 bytes, sequence
 | 
				
			||||||
 | 
					              + '06 03 55 1D 11'            // 9+n    5 bytes, object id (subjectAltName (X.509 extension))
 | 
				
			||||||
 | 
					              + '04 {23.8.0octlen}'         // 4+n    2 bytes, octet string
 | 
				
			||||||
 | 
					                + '30 {24.9.0seqlen}'       // 2+n    2 bytes, sequence
 | 
				
			||||||
 | 
					                  + '{altnames}'            // n      n bytes
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function privateToPub(pem) {
 | 
				
			||||||
 | 
					  var pubbuf;
 | 
				
			||||||
 | 
					  var key = pubkey.parsePem(pem);
 | 
				
			||||||
 | 
					  if ('RSA' !== key.typ) {
 | 
				
			||||||
 | 
					    throw new Error(key.typ + " not supported");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (key.pub) {
 | 
				
			||||||
 | 
					    pubbuf = pubkey.readPubkey(key.der);
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    pubbuf = pubkey.readPrivkey(key.der);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //console.log(pubbuf.byteLength, pubkey.toHex(pubbuf));
 | 
				
			||||||
 | 
					  var der = pubkey.toRsaPub(pubbuf);
 | 
				
			||||||
 | 
					  var b64 = pubkey.toBase64(der);
 | 
				
			||||||
 | 
					  return pubkey.formatAsPublicPem(b64);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function strToHex(str) {
 | 
				
			||||||
 | 
					  return str.split('').map(function (ch) {
 | 
				
			||||||
 | 
					    var h = ch.charCodeAt(0).toString(16);
 | 
				
			||||||
 | 
					    if (2 === h.length) {
 | 
				
			||||||
 | 
					      return h;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return '0' + h;
 | 
				
			||||||
 | 
					  }).join('');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function pubToPem(pubbuf) {
 | 
				
			||||||
 | 
					  var der = pubkey.toRsaPub(pubbuf);
 | 
				
			||||||
 | 
					  var b64 = pubkey.toBase64(der);
 | 
				
			||||||
 | 
					  return pubkey.formatAsPublicPem(b64);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var sigend = (csrFull.byteLength - (2048 / 8));
 | 
				
			||||||
 | 
					var sig = csrFull.slice(sigend);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					console.log();
 | 
				
			||||||
 | 
					console.log();
 | 
				
			||||||
 | 
					console.log('csr (' + csrFull.byteLength + ')');
 | 
				
			||||||
 | 
					console.log(pubkey.toHex(csrFull));
 | 
				
			||||||
 | 
					console.log();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// First 4 bytes define Segment, segment length, and content length
 | 
				
			||||||
 | 
					console.log(sigend, csrRsaFoot, csrRsaFoot.length/2);
 | 
				
			||||||
 | 
					var csrbody = csrFull.slice(4, sigend - (csrRsaFoot.length/2));
 | 
				
			||||||
 | 
					console.log('csr body (' + csrbody.byteLength + ')');
 | 
				
			||||||
 | 
					console.log(pubkey.toHex(csrbody));
 | 
				
			||||||
 | 
					console.log();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var csrpub = csrFull.slice(63 + 5, 63 + 5 + 256);
 | 
				
			||||||
 | 
					console.log('csr pub (' + csrpub.byteLength + ')');
 | 
				
			||||||
 | 
					console.log(pubkey.toHex(csrpub));
 | 
				
			||||||
 | 
					console.log();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					console.log('sig (' + sig.byteLength + ')');
 | 
				
			||||||
 | 
					console.log(pubkey.toHex(sig));
 | 
				
			||||||
 | 
					console.log();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var csrpem = pubToPem(csrpub);
 | 
				
			||||||
 | 
					console.log(csrpem);
 | 
				
			||||||
 | 
					console.log();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var prvpem = privateToPub(keypem);
 | 
				
			||||||
 | 
					console.log(prvpem);
 | 
				
			||||||
 | 
					console.log();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (csrpem === prvpem) {
 | 
				
			||||||
 | 
					  console.log("Public Keys Match");
 | 
				
			||||||
 | 
					} else {
 | 
				
			||||||
 | 
					  throw new Error("public key read from keyfile doesn't match public key read from CSR");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function h(d) {
 | 
				
			||||||
 | 
					  d = d.toString(16);
 | 
				
			||||||
 | 
					  if (d.length % 2) {
 | 
				
			||||||
 | 
					    return '0' + d;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return d;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function fromHex(hex) {
 | 
				
			||||||
 | 
					  if ('undefined' !== typeof Buffer) {
 | 
				
			||||||
 | 
					    return Buffer.from(hex, 'hex');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  var ab = new ArrayBuffer(hex.length/2);
 | 
				
			||||||
 | 
					  var i;
 | 
				
			||||||
 | 
					  var j;
 | 
				
			||||||
 | 
					  ab = new Uint8Array(ab);
 | 
				
			||||||
 | 
					  for (i = 0, j = 0; i < (hex.length/2); i += 1) {
 | 
				
			||||||
 | 
					    ab[i] = parseInt(hex.slice(j, j+1), 16);
 | 
				
			||||||
 | 
					    j += 2;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return ab.buffer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function createCsrBodyRsa(domains, csrpub) {
 | 
				
			||||||
 | 
					  var altnames = domains.map(function (d) {
 | 
				
			||||||
 | 
					    return csrDomains.replace(/{dlen}/, h(d.length)).replace(/{domain\.tld}/, strToHex(d));
 | 
				
			||||||
 | 
					  }).join('').replace(/\s+/g, '');
 | 
				
			||||||
 | 
					  var publen = csrpub.byteLength;
 | 
				
			||||||
 | 
					  var sublen = domains[0].length;
 | 
				
			||||||
 | 
					  var sanlen = (altnames.length/2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var body = [ '30 82 {1.1.0seqlen}'                                  // 4 bytes, sequence
 | 
				
			||||||
 | 
					    .replace(/{[^}]+}/, h(
 | 
				
			||||||
 | 
					        3
 | 
				
			||||||
 | 
					      + 13 + sublen
 | 
				
			||||||
 | 
					      + 38 + publen
 | 
				
			||||||
 | 
					      + 30 + sanlen
 | 
				
			||||||
 | 
					    ))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // #0 Total 3
 | 
				
			||||||
 | 
					    , '02 01 00'                                                      // 3 bytes, int 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // #1 Total 2+11+n
 | 
				
			||||||
 | 
					    , '30 {3.2.0seqlen}'                                              // 2 bytes, sequence
 | 
				
			||||||
 | 
					      .replace(/{[^}]+}/, h(2+2+5+2+sublen))
 | 
				
			||||||
 | 
					      , '31 {4.3.0setlen}'                                            // 2 bytes, set
 | 
				
			||||||
 | 
					        .replace(/{[^}]+}/, h(2+5+2+sublen))
 | 
				
			||||||
 | 
					        , '30 {5.4.0seqlen}'                                          // 2 bytes, sequence
 | 
				
			||||||
 | 
					          .replace(/{[^}]+}/, h(5+2+sublen))
 | 
				
			||||||
 | 
					        , '06 03 55 04 03'                                            // 5 bytes, object id (commonName)
 | 
				
			||||||
 | 
					        , '0C {dlen} {domain.tld}'                                    // 2+n bytes, utf8string
 | 
				
			||||||
 | 
					          .replace(/{dlen}/, h(sublen))
 | 
				
			||||||
 | 
					          .replace(/{domain\.tld}/, strToHex(domains[0]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // #2 Total 4+28+n+1+5
 | 
				
			||||||
 | 
					    , '30 82 {8.2.2seqlen}'                                           // 4 bytes, sequence
 | 
				
			||||||
 | 
					      .replace(/{[^}]+}/, h(2+11+2+4+1+4+4+publen+1+5))
 | 
				
			||||||
 | 
					      , '30 0D'                                                       // 2 bytes, sequence
 | 
				
			||||||
 | 
					        , '06 09 2A 86 48 86 F7 0D 01 01 01'                          // 11 bytes, rsaEncryption (PKCS #1)
 | 
				
			||||||
 | 
					        , '05 00'                                                     // 2 bytes, null (why?)
 | 
				
			||||||
 | 
					      , '03 82 {12.3.0bslen} 00'                                      // 4+1 bytes, bit string [01 0F]
 | 
				
			||||||
 | 
					        .replace(/{[^}]+}/, h(1+4+4+publen+1+5))
 | 
				
			||||||
 | 
					        , '30 82 {13.4.0seqlen}'                                      // 4 bytes, sequence
 | 
				
			||||||
 | 
					          .replace(/{[^}]+}/, h(4+publen+1+5))
 | 
				
			||||||
 | 
					        , '02 82 {klen} 00 {key}'                                     // 4+n bytes, int (RSA Pub Key)
 | 
				
			||||||
 | 
					          .replace(/{klen}/, h(publen+1))
 | 
				
			||||||
 | 
					          .replace(/{key}/, pubkey.toHex(csrpub))
 | 
				
			||||||
 | 
					        , '02 03 {mod}'                                               // 5 bytes, key and modules [01 00 01]
 | 
				
			||||||
 | 
					          .replace(/{mod}/, '01 00 01')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // #3 Total 2+28+n
 | 
				
			||||||
 | 
					    , 'A0 {16.2.3ellen}'                                              // 2 bytes, ?? [4B]
 | 
				
			||||||
 | 
					      .replace(/{[^}]+}/, h(2+11+2+2+2+5+2+2+sanlen))
 | 
				
			||||||
 | 
					      , '30 {17.3.9seqlen}'                                           // 2 bytes, sequence
 | 
				
			||||||
 | 
					        .replace(/{[^}]+}/, h(11+2+2+2+5+2+2+sanlen))
 | 
				
			||||||
 | 
					        , '06 09 2A 86 48 86 F7 0D 01 09 0E'                          // 11 bytes, object id (extensionRequest (PKCS #9 via CRMF))
 | 
				
			||||||
 | 
					          , '31 {19.5.0setlen}'                                       // 2 bytes, set
 | 
				
			||||||
 | 
					            .replace(/{[^}]+}/, h(2+2+5+2+2+sanlen))
 | 
				
			||||||
 | 
					            , '30 {20.6.0seqlen}'                                     // 2 bytes, sequence
 | 
				
			||||||
 | 
					              .replace(/{[^}]+}/, h(2+5+2+2+sanlen))
 | 
				
			||||||
 | 
					              , '30 {21.7.0seqlen}'                                   // 2 bytes, sequence
 | 
				
			||||||
 | 
					                .replace(/{[^}]+}/, h(5+2+2+sanlen))
 | 
				
			||||||
 | 
					                , '06 03 55 1D 11'                                    // 5 bytes, object id (subjectAltName (X.509 extension))
 | 
				
			||||||
 | 
					                , '04 {23.8.0octlen}'                                 // 2 bytes, octet string
 | 
				
			||||||
 | 
					                  .replace(/{[^}]+}/, h(2+sanlen))
 | 
				
			||||||
 | 
					                  , '30 {24.9.0seqlen}'                               // 2 bytes, sequence
 | 
				
			||||||
 | 
					                    .replace(/{[^}]+}/, h(sanlen))
 | 
				
			||||||
 | 
					                    , '{altnames}'                                    // n (elements of sequence)
 | 
				
			||||||
 | 
					                      .replace(/{altnames}/, altnames)
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					  body = body.join('').replace(/\s+/g, '');
 | 
				
			||||||
 | 
					  return fromHex(body);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function createCsrBodyEc(domains, csrpub) {
 | 
				
			||||||
 | 
					  var altnames = domains.map(function (d) {
 | 
				
			||||||
 | 
					    return csrDomains.replace(/{dlen}/, h(d.length)).replace(/{domain\.tld}/, strToHex(d));
 | 
				
			||||||
 | 
					  }).join('').replace(/\s+/g, '');
 | 
				
			||||||
 | 
					  var publen = csrpub.byteLength;
 | 
				
			||||||
 | 
					  var sublen = domains[0].length;
 | 
				
			||||||
 | 
					  var sanlen = (altnames.length/2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var body = [ '30 82 {1.1.0seqlen}'                                  // 4 bytes, sequence
 | 
				
			||||||
 | 
					    .replace(/{[^}]+}/, h(
 | 
				
			||||||
 | 
					        3
 | 
				
			||||||
 | 
					      + 13 + sublen
 | 
				
			||||||
 | 
					      + 38 + publen
 | 
				
			||||||
 | 
					      + 30 + sanlen
 | 
				
			||||||
 | 
					    ))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // #0 Total 3
 | 
				
			||||||
 | 
					    , '02 01 00'                                                      // 3 bytes, int 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // #1 Total 2+11+n
 | 
				
			||||||
 | 
					    , '30 {3.2.0seqlen}'                                              // 2 bytes, sequence
 | 
				
			||||||
 | 
					      .replace(/{[^}]+}/, h(2+2+5+2+sublen))
 | 
				
			||||||
 | 
					      , '31 {4.3.0setlen}'                                            // 2 bytes, set
 | 
				
			||||||
 | 
					        .replace(/{[^}]+}/, h(2+5+2+sublen))
 | 
				
			||||||
 | 
					        , '30 {5.4.0seqlen}'                                          // 2 bytes, sequence
 | 
				
			||||||
 | 
					          .replace(/{[^}]+}/, h(5+2+sublen))
 | 
				
			||||||
 | 
					        , '06 03 55 04 03'                                            // 5 bytes, object id (commonName)
 | 
				
			||||||
 | 
					        , '0C {dlen} {domain.tld}'                                    // 2+n bytes, utf8string
 | 
				
			||||||
 | 
					          .replace(/{dlen}/, h(sublen))
 | 
				
			||||||
 | 
					          .replace(/{domain\.tld}/, strToHex(domains[0]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // #2 Total 4+28+n+1+5
 | 
				
			||||||
 | 
					    , '30 82 {8.2.2seqlen}'                                           // 4 bytes, sequence
 | 
				
			||||||
 | 
					      .replace(/{[^}]+}/, h(2+11+2+4+1+4+4+publen+1+5))
 | 
				
			||||||
 | 
					      , '30 0D'                                                       // 2 bytes, sequence
 | 
				
			||||||
 | 
					        , '06 09 2A 86 48 86 F7 0D 01 01 01'                          // 11 bytes, rsaEncryption (PKCS #1)
 | 
				
			||||||
 | 
					        , '05 00'                                                     // 2 bytes, null (why?)
 | 
				
			||||||
 | 
					      , '03 82 {12.3.0bslen} 00'                                      // 4+1 bytes, bit string [01 0F]
 | 
				
			||||||
 | 
					        .replace(/{[^}]+}/, h(1+4+4+publen+1+5))
 | 
				
			||||||
 | 
					        , '30 82 {13.4.0seqlen}'                                      // 4 bytes, sequence
 | 
				
			||||||
 | 
					          .replace(/{[^}]+}/, h(4+publen+1+5))
 | 
				
			||||||
 | 
					        , '02 82 {klen} 00 {key}'                                     // 4+n bytes, int (RSA Pub Key)
 | 
				
			||||||
 | 
					          .replace(/{klen}/, h(publen+1))
 | 
				
			||||||
 | 
					          .replace(/{key}/, pubkey.toHex(csrpub))
 | 
				
			||||||
 | 
					        , '02 03 {mod}'                                               // 5 bytes, key and modules [01 00 01]
 | 
				
			||||||
 | 
					          .replace(/{mod}/, '01 00 01')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // #3 Total 2+28+n
 | 
				
			||||||
 | 
					    , 'A0 {16.2.3ellen}'                                              // 2 bytes, ?? [4B]
 | 
				
			||||||
 | 
					      .replace(/{[^}]+}/, h(2+11+2+2+2+5+2+2+sanlen))
 | 
				
			||||||
 | 
					      , '30 {17.3.9seqlen}'                                           // 2 bytes, sequence
 | 
				
			||||||
 | 
					        .replace(/{[^}]+}/, h(11+2+2+2+5+2+2+sanlen))
 | 
				
			||||||
 | 
					        , '06 09 2A 86 48 86 F7 0D 01 09 0E'                          // 11 bytes, object id (extensionRequest (PKCS #9 via CRMF))
 | 
				
			||||||
 | 
					          , '31 {19.5.0setlen}'                                       // 2 bytes, set
 | 
				
			||||||
 | 
					            .replace(/{[^}]+}/, h(2+2+5+2+2+sanlen))
 | 
				
			||||||
 | 
					            , '30 {20.6.0seqlen}'                                     // 2 bytes, sequence
 | 
				
			||||||
 | 
					              .replace(/{[^}]+}/, h(2+5+2+2+sanlen))
 | 
				
			||||||
 | 
					              , '30 {21.7.0seqlen}'                                   // 2 bytes, sequence
 | 
				
			||||||
 | 
					                .replace(/{[^}]+}/, h(5+2+2+sanlen))
 | 
				
			||||||
 | 
					                , '06 03 55 1D 11'                                    // 5 bytes, object id (subjectAltName (X.509 extension))
 | 
				
			||||||
 | 
					                , '04 {23.8.0octlen}'                                 // 2 bytes, octet string
 | 
				
			||||||
 | 
					                  .replace(/{[^}]+}/, h(2+sanlen))
 | 
				
			||||||
 | 
					                  , '30 {24.9.0seqlen}'                               // 2 bytes, sequence
 | 
				
			||||||
 | 
					                    .replace(/{[^}]+}/, h(sanlen))
 | 
				
			||||||
 | 
					                    , '{altnames}'                                    // n (elements of sequence)
 | 
				
			||||||
 | 
					                      .replace(/{altnames}/, altnames)
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					  body = body.join('').replace(/\s+/g, '');
 | 
				
			||||||
 | 
					  return fromHex(body);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function createCsr(domains, keypem) {
 | 
				
			||||||
 | 
					  // TODO get pub from priv
 | 
				
			||||||
 | 
					  var body = createCsrBodyRsa(domains, csrpub);
 | 
				
			||||||
 | 
					  var sign = crypto.createSign('SHA256');
 | 
				
			||||||
 | 
					  sign.write(new Uint8Array(body));
 | 
				
			||||||
 | 
					  sign.end();
 | 
				
			||||||
 | 
					  var sig = sign.sign(keypem);
 | 
				
			||||||
 | 
					  var len = body.byteLength + (csrRsaFoot.length/2) + sig.byteLength;
 | 
				
			||||||
 | 
					  console.log('headlen', h(len));
 | 
				
			||||||
 | 
					  var head = csrHead.replace(/{[^}]+}/, h(len));
 | 
				
			||||||
 | 
					  var ab = new Uint8Array(new ArrayBuffer(4 + len));
 | 
				
			||||||
 | 
					  var i = 0;
 | 
				
			||||||
 | 
					  fromHex(head).forEach(function (b) {
 | 
				
			||||||
 | 
					    ab[i] = b;
 | 
				
			||||||
 | 
					    i += 1;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  body.forEach(function (b) {
 | 
				
			||||||
 | 
					    ab[i] = b;
 | 
				
			||||||
 | 
					    i += 1;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  fromHex(csrRsaFoot).forEach(function (b) {
 | 
				
			||||||
 | 
					    ab[i] = b;
 | 
				
			||||||
 | 
					    i += 1;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  new Uint8Array(sig).forEach(function (b) {
 | 
				
			||||||
 | 
					    ab[i] = b;
 | 
				
			||||||
 | 
					    i += 1;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var pem = pubkey.formatAsPublicPem(pubkey.toBase64(ab));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return pem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//var pem = createCsr([ 'example.com', 'www.example.com', 'api.example.com' ], keypem);
 | 
				
			||||||
 | 
					var pem = createCsr([ 'whatever.net', 'api.whatever.net' ], keypem);
 | 
				
			||||||
 | 
					console.log('pem:');
 | 
				
			||||||
 | 
					console.log(pem);
 | 
				
			||||||
 | 
					return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function signagain(csrbody) {
 | 
				
			||||||
 | 
					  var longEnough = csrbody.byteLength > 256;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!longEnough) { return false; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var domains = [ 'example.com', 'www.example.com', 'api.example.com' ];
 | 
				
			||||||
 | 
					  var body = createCsrBodyRsa(domains);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var sign = crypto.createSign('SHA256');
 | 
				
			||||||
 | 
					  sign.write(new Uint8Array(body));
 | 
				
			||||||
 | 
					  sign.end();
 | 
				
			||||||
 | 
					  var sig2 = sign.sign(keypem);
 | 
				
			||||||
 | 
					  var hexsig = pubkey.toHex(sig);
 | 
				
			||||||
 | 
					  var hexsig2 = pubkey.toHex(sig2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  console.log('hexsig:');
 | 
				
			||||||
 | 
					  console.log(hexsig);
 | 
				
			||||||
 | 
					  if (hexsig2 !== hexsig) {
 | 
				
			||||||
 | 
					    throw new Error("sigs didn't match");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  console.log('Winner winner!', csrbody.byteLength);
 | 
				
			||||||
 | 
					  console.log(pubkey.toHex(csrbody));
 | 
				
			||||||
 | 
					  console.log();
 | 
				
			||||||
 | 
					  console.log('Test:', body.byteLength);
 | 
				
			||||||
 | 
					  console.log(pubkey.toHex(body));
 | 
				
			||||||
 | 
					  console.log();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var len = body.byteLength + (csrRsaFoot.length/2) + sig.byteLength;
 | 
				
			||||||
 | 
					  console.log('headlen', h(len));
 | 
				
			||||||
 | 
					  var head = csrHead.replace(/{[^}]+}/, h(len));
 | 
				
			||||||
 | 
					  var ab = new Uint8Array(new ArrayBuffer(4 + len));
 | 
				
			||||||
 | 
					  var i = 0;
 | 
				
			||||||
 | 
					  fromHex(head).forEach(function (b) {
 | 
				
			||||||
 | 
					    ab[i] = b;
 | 
				
			||||||
 | 
					    i += 1;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  body.forEach(function (b) {
 | 
				
			||||||
 | 
					    ab[i] = b;
 | 
				
			||||||
 | 
					    i += 1;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  fromHex(csrRsaFoot).forEach(function (b) {
 | 
				
			||||||
 | 
					    ab[i] = b;
 | 
				
			||||||
 | 
					    i += 1;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  new Uint8Array(sig2).forEach(function (b) {
 | 
				
			||||||
 | 
					    ab[i] = b;
 | 
				
			||||||
 | 
					    i += 1;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  console.log("Whole enchilada:", pubkey.toHex(ab.buffer) === pubkey.toHex(csrFull));
 | 
				
			||||||
 | 
					  console.log(pubkey.toHex(ab.buffer));
 | 
				
			||||||
 | 
					  console.log();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // subject + 2-byte altname headers + altnames themselves + public key
 | 
				
			||||||
 | 
					  //var extralen = domains[0].length + (domains.length * 2) + domains.join('').length + csrpub.byteLength;
 | 
				
			||||||
 | 
					  //var foot = csrRsaFoot.replace(/xxxx/g, (csrpub.byteLength + 1));
 | 
				
			||||||
 | 
					  //var head = csrHead.replace(/xxxx/);
 | 
				
			||||||
 | 
					  return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					console.log();
 | 
				
			||||||
 | 
					console.log("CSR");
 | 
				
			||||||
 | 
					console.log(pubkey.toHex(csrFull));
 | 
				
			||||||
 | 
					console.log();
 | 
				
			||||||
 | 
					console.log(pubkey.toHex(csrbody.slice(0, csrbody.byteLength - sig.byteLength)));
 | 
				
			||||||
 | 
					console.log();
 | 
				
			||||||
 | 
					console.log();
 | 
				
			||||||
 | 
					//signagain(csrbody);
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user