'use strict'; var ASN1 = require('../'); var Enc = require('@root/encoding'); var PEM = require('@root/pem'); // 1.2.840.10045.3.1.7 // prime256v1 (ANSI X9.62 named elliptic curve) var OBJ_ID_EC_256 = '06 08 2A8648CE3D030107'; var jwk = { crv: 'P-256', d: 'LImWxqqTHbP3LHQfqscDSUzf_uNePGqf9U6ETEcO5Ho', kty: 'EC', x: 'vdjQ3T6VBX82LIKDzepYgRsz3HgRwp83yPuonu6vqos', y: 'IUkEXtAMnppnV1A19sE2bJhUo4WPbq6EYgWxma4oGyg', kid: 'MnfJYyS9W5gUjrJLdn8ePMzik8ZJz2qc-VZmKOs_oCw' }; var d = Enc.base64ToHex(jwk.d); var x = Enc.base64ToHex(jwk.x); var y = Enc.base64ToHex(jwk.y); var der = Enc.hexToBuf( ASN1.Any( '30', // Sequence ASN1.UInt('01'), // Integer (Version 1) ASN1.Any('04', d), // Octet String ASN1.Any('A0', OBJ_ID_EC_256), // [0] Object ID ASN1.Any( 'A1', // [1] Embedded EC/ASN1 public key ASN1.BitStr('04' + x + y) ) ) ); var pem1 = PEM.packBlock({ type: 'EC PRIVATE KEY', bytes: der }); var expected = [ '-----BEGIN EC PRIVATE KEY-----', 'MHcCAQEEICyJlsaqkx2z9yx0H6rHA0lM3/7jXjxqn/VOhExHDuR6oAoGCCqGSM49', 'AwEHoUQDQgAEvdjQ3T6VBX82LIKDzepYgRsz3HgRwp83yPuonu6vqoshSQRe0Aye', 'mmdXUDX2wTZsmFSjhY9uroRiBbGZrigbKA==', '-----END EC PRIVATE KEY-----' ].join('\n'); if (pem1 !== expected) { throw new Error('Did not correctly Cascade pack EC P-256 JWK to DER'); } else { console.info('PASS: packed cascaded ASN1'); } // Mix and match hex ints, hex strings, and byte arrays var asn1Arr = [ '30', // Sequence [ [0x02, '01'], // Integer (Version 1) [0x04, Buffer.from(d, 'hex')], // Octet String ['a0', OBJ_ID_EC_256], // [0] Object ID [ 0xa1, // [1] Embedded EC/ASN1 public key ASN1.BitStr('04' + x + y) ] ] ]; var der2 = ASN1.pack(asn1Arr); var pem2 = PEM.packBlock({ type: 'EC PRIVATE KEY', bytes: der2 }); if (pem2 !== expected) { console.log(pem2); console.log(expected); throw new Error('Did not correctly Array pack EC P-256 JWK to DER'); } else { console.info('PASS: packed array-style ASN1'); } var block = PEM.parseBlock(expected); var arr1 = ASN1.parse({ der: block.bytes }); //console.log(JSON.stringify(arr1)); var arr2 = ASN1.parse({ der: block.bytes, verbose: false, json: false }); var obj3 = ASN1.parse({ der: block.bytes, verbose: true, json: true }); //console.log(obj3); function eq(b1, b2) { if (b1.byteLength !== b2.byteLength) { return false; } return b1.every(function(b, i) { return b === b2[i]; }); } if (!eq(block.bytes, ASN1.pack(arr1))) { throw new Error('packing hex array resulted in different bytes'); } else { console.log('PASS: packs parsed (hex) array'); } if (!eq(block.bytes, ASN1.pack(arr2))) { throw new Error('packing array with bytes resulted in different bytes'); } else { console.log('PASS: packs parsed array (with bytes)'); } if (!eq(block.bytes, ASN1.pack(obj3))) { console.log(block.bytes.toString('hex')); console.log(ASN1.pack(obj3)); throw new Error('packing verbose object resulted in different bytes'); } else { console.log('PASS: packs parsed verbose object'); } if (block.bytes.toString('hex') !== ASN1.pack(obj3, { json: true })) { throw new Error('packing to hex resulted in different bytes'); } else { console.log('PASS: packs as hex when json: true'); }