260 lines
7.2 KiB
JavaScript
Executable file
260 lines
7.2 KiB
JavaScript
Executable file
/**
|
|
* Created by bmf on 11/2/13.
|
|
*/
|
|
/* jslint node: true */
|
|
'use strict';
|
|
|
|
var assert = require('assert');
|
|
var CryptoBaseBuffer = require('../crypto-base-buffer');
|
|
|
|
module.exports = function KeyPair() {
|
|
var self = this;
|
|
|
|
/** secret key */
|
|
self.secretKey = new CryptoBaseBuffer();
|
|
self.secretKeySize = 0;
|
|
|
|
/** public key */
|
|
self.publicKey = new CryptoBaseBuffer();
|
|
self.publicKeySize = 0;
|
|
|
|
self.type = undefined;
|
|
|
|
/** default encoding to use in all string operations */
|
|
self.defaultEncoding = undefined;
|
|
|
|
self.init = function(options) {
|
|
options = options || {};
|
|
|
|
if( !options.type ) {
|
|
throw new Error('[KeyPair] type not given in init');
|
|
}
|
|
self.type = options.type;
|
|
|
|
if( !options.publicKeySize ) {
|
|
throw new Error('[KeyPair] public key size not given');
|
|
}
|
|
self.publicKeySize = options.publicKeySize;
|
|
|
|
if( !options.secretKeySize ) {
|
|
throw new Error('[KeyPair] secret key size not given');
|
|
}
|
|
self.secretKeySize = options.secretKeySize;
|
|
|
|
// init both buffers
|
|
self.publicKey.init({
|
|
expectedSize: options.publicKeySize,
|
|
type: self.type + 'PublicKey'
|
|
});
|
|
|
|
self.secretKey.init({
|
|
expectedSize: options.secretKeySize,
|
|
type: self.type + 'SecretKey'
|
|
});
|
|
|
|
// We will only accept hex string representations of keys
|
|
self.publicKey.setValidEncodings(['hex', 'base64']);
|
|
self.secretKey.setValidEncodings(['hex', 'base64']);
|
|
|
|
// the default encoding to us in all string set/toString methods is Hex
|
|
self.publicKey.setEncoding('base64');
|
|
self.secretKey.setEncoding('base64');
|
|
|
|
// Public Key
|
|
self.setPublicKey(options.publicKey, options.encoding);
|
|
|
|
// Secret Key
|
|
self.setSecretKey(options.secretKey, options.encoding);
|
|
};
|
|
|
|
/** Box Public Key buffer size in bytes */
|
|
self.publicKeyBytes = function() {
|
|
return self.publicKeySize;
|
|
};
|
|
|
|
/** Box Public Key buffer size in bytes */
|
|
self.secretKeyBytes = function() {
|
|
return self.secretKeySize;
|
|
};
|
|
|
|
/* Aliases */
|
|
self.pkBytes = self.publicKeyBytes;
|
|
self.skBytes = self.secretKeyBytes;
|
|
|
|
/**
|
|
* Set the default encoding to use in all string conversions
|
|
* @param {String} encoding encoding to use
|
|
*/
|
|
self.setEncoding = function(encoding) {
|
|
assert(!!encoding.match(/^(?:utf8|ascii|binary|hex|utf16le|ucs2|base64)$/), 'Encoding ' + encoding + ' is currently unsupported.');
|
|
self.defaultEncoding = encoding;
|
|
self.publicKey.setEncoding(encoding);
|
|
self.secretKey.setEncoding(encoding);
|
|
};
|
|
|
|
/**
|
|
* Get the current default encoding
|
|
* @returns {undefined|String}
|
|
*/
|
|
self.getEncoding = function() {
|
|
return self.defaultEncoding;
|
|
};
|
|
|
|
/**
|
|
* Check if key pair is valid
|
|
* @param keys {Object} an object with secrteKey, and publicKey members
|
|
* @returns {boolean} true is both public and secret keys are valid
|
|
*/
|
|
self.isValid = function(keys, encoding) {
|
|
assert.equal(typeof keys, 'object');
|
|
assert.ok(keys.publicKey);
|
|
assert.ok(keys.secretKey);
|
|
|
|
encoding = encoding || self.defaultEncoding;
|
|
|
|
return self.publicKey.isValid(keys.publicKey, encoding) &&
|
|
self.secretKey.isValid(keys.secretKey, encoding);
|
|
};
|
|
|
|
/**
|
|
* Wipe keys securely
|
|
*/
|
|
self.wipe = function() {
|
|
self.publicKey.wipe();
|
|
self.secretKey.wipe();
|
|
};
|
|
|
|
/**
|
|
* Generate a random key pair
|
|
*/
|
|
self.generate = function() {
|
|
throw new Error('KeyPair: this method should be implemented in each sub class');
|
|
};
|
|
|
|
/**
|
|
* Getter for the public key
|
|
* @returns {undefined| Buffer} public key
|
|
*/
|
|
self.getPublicKey = function() {
|
|
return self.publicKey;
|
|
};
|
|
|
|
/**
|
|
* Getter for the secretKey
|
|
* @returns {undefined| Buffer} secret key
|
|
*/
|
|
self.getSecretKey = function() {
|
|
return self.secretKey;
|
|
};
|
|
|
|
self.pk = self.getPublicKey;
|
|
self.sk = self.getSecretKey;
|
|
|
|
/**
|
|
* Getter for the key pair
|
|
* @returns {Object} with both public and private keys
|
|
*/
|
|
self.get = function() {
|
|
return {
|
|
'publicKey' : self.publicKey.get(),
|
|
'secretKey' : self.secretKey.get()
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Set the secret key to a known value
|
|
* @param v {String|Buffer|Array} the secret key
|
|
* @param encoding {String} optional. If v is a string you can specify the encoding
|
|
*/
|
|
self.set = function(keys, encoding) {
|
|
assert.equal(typeof keys, 'object');
|
|
|
|
if( keys instanceof KeyPair ) {
|
|
self.secretKey.set(keys.sk(), encoding);
|
|
self.publicKey.set(keys.pk(), encoding);
|
|
}
|
|
else {
|
|
encoding = encoding || self.defaultEncoding;
|
|
if( typeof keys === 'object' ) {
|
|
if( keys.secretKey ) {
|
|
self.secretKey.set(keys.secretKey, encoding);
|
|
}
|
|
if( keys.publicKey ) {
|
|
self.publicKey.set(keys.publicKey, encoding);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
self.setPublicKey = function(key, encoding) {
|
|
if( key instanceof KeyPair ) {
|
|
self.publicKey = key.pk();
|
|
}
|
|
else if( key instanceof CryptoBaseBuffer ) {
|
|
if( key.size() == self.publicKeySize ) {
|
|
self.publicKey = key;
|
|
}
|
|
}
|
|
else {
|
|
self.publicKey.init({
|
|
expectedSize: self.publicKeySize,
|
|
buffer: key,
|
|
encoding: encoding,
|
|
type: self.type + 'PublicKey'
|
|
});
|
|
}
|
|
};
|
|
|
|
self.setSecretKey = function(key, encoding) {
|
|
if( key instanceof KeyPair ) {
|
|
self.secretKey = key.sk();
|
|
}
|
|
else if( key instanceof CryptoBaseBuffer ) {
|
|
if( key.size() == self.secretKeySize ) {
|
|
self.secretKey = key;
|
|
}
|
|
}
|
|
else {
|
|
self.secretKey.init({
|
|
expectedSize: self.secretKeySize,
|
|
buffer: key,
|
|
encoding: encoding,
|
|
type: self.type + 'SecretKey'
|
|
});
|
|
}
|
|
};
|
|
|
|
|
|
/**
|
|
* Convert the secret key to a string object
|
|
* @param encoding {String} optional sting encoding. defaults to 'hex'
|
|
*/
|
|
self.toString = function(encoding) {
|
|
encoding = encoding || self.defaultEncoding;
|
|
|
|
return self.secretKey.toString(encoding) + "," +
|
|
self.publicKey.toString(encoding);
|
|
};
|
|
|
|
/**
|
|
* Convert the secret key to a JSON object
|
|
* @param encoding {String} optional sting encoding. defaults to 'hex'
|
|
*/
|
|
self.toJson = function(encoding) {
|
|
encoding = encoding || self.defaultEncoding;
|
|
|
|
var out = '{';
|
|
if( self.secretKey ) {
|
|
out += '"secretKey" :"' + self.secretKey.toString(encoding) + '"';
|
|
}
|
|
if( self.secretKey && self.publicKey ) {
|
|
out += ', ';
|
|
}
|
|
if( self.publicKey ) {
|
|
out += '"publicKey" :"' + self.publicKey.toString(encoding) + '"';
|
|
}
|
|
out += '}';
|
|
return out;
|
|
};
|
|
};
|