1// Copyright 2015 Joyent, Inc. 2 3module.exports = { 4 Verifier: Verifier, 5 Signer: Signer 6}; 7 8var nacl; 9var stream = require('stream'); 10var util = require('util'); 11var assert = require('assert-plus'); 12var Buffer = require('safer-buffer').Buffer; 13var Signature = require('./signature'); 14 15function Verifier(key, hashAlgo) { 16 if (nacl === undefined) 17 nacl = require('tweetnacl'); 18 19 if (hashAlgo.toLowerCase() !== 'sha512') 20 throw (new Error('ED25519 only supports the use of ' + 21 'SHA-512 hashes')); 22 23 this.key = key; 24 this.chunks = []; 25 26 stream.Writable.call(this, {}); 27} 28util.inherits(Verifier, stream.Writable); 29 30Verifier.prototype._write = function (chunk, enc, cb) { 31 this.chunks.push(chunk); 32 cb(); 33}; 34 35Verifier.prototype.update = function (chunk) { 36 if (typeof (chunk) === 'string') 37 chunk = Buffer.from(chunk, 'binary'); 38 this.chunks.push(chunk); 39}; 40 41Verifier.prototype.verify = function (signature, fmt) { 42 var sig; 43 if (Signature.isSignature(signature, [2, 0])) { 44 if (signature.type !== 'ed25519') 45 return (false); 46 sig = signature.toBuffer('raw'); 47 48 } else if (typeof (signature) === 'string') { 49 sig = Buffer.from(signature, 'base64'); 50 51 } else if (Signature.isSignature(signature, [1, 0])) { 52 throw (new Error('signature was created by too old ' + 53 'a version of sshpk and cannot be verified')); 54 } 55 56 assert.buffer(sig); 57 return (nacl.sign.detached.verify( 58 new Uint8Array(Buffer.concat(this.chunks)), 59 new Uint8Array(sig), 60 new Uint8Array(this.key.part.A.data))); 61}; 62 63function Signer(key, hashAlgo) { 64 if (nacl === undefined) 65 nacl = require('tweetnacl'); 66 67 if (hashAlgo.toLowerCase() !== 'sha512') 68 throw (new Error('ED25519 only supports the use of ' + 69 'SHA-512 hashes')); 70 71 this.key = key; 72 this.chunks = []; 73 74 stream.Writable.call(this, {}); 75} 76util.inherits(Signer, stream.Writable); 77 78Signer.prototype._write = function (chunk, enc, cb) { 79 this.chunks.push(chunk); 80 cb(); 81}; 82 83Signer.prototype.update = function (chunk) { 84 if (typeof (chunk) === 'string') 85 chunk = Buffer.from(chunk, 'binary'); 86 this.chunks.push(chunk); 87}; 88 89Signer.prototype.sign = function () { 90 var sig = nacl.sign.detached( 91 new Uint8Array(Buffer.concat(this.chunks)), 92 new Uint8Array(Buffer.concat([ 93 this.key.part.k.data, this.key.part.A.data]))); 94 var sigBuf = Buffer.from(sig); 95 var sigObj = Signature.parse(sigBuf, 'ed25519', 'raw'); 96 sigObj.hashAlgorithm = 'sha512'; 97 return (sigObj); 98}; 99