2016-05-19 18:47:48 +02:00
|
|
|
'use strict'
|
|
|
|
|
2016-05-19 21:45:43 +02:00
|
|
|
const protobuf = require('protocol-buffers')
|
2017-01-16 05:17:50 +01:00
|
|
|
|
2016-09-13 13:23:11 +02:00
|
|
|
const pbm = protobuf(require('./crypto.proto'))
|
|
|
|
const c = require('./crypto')
|
2016-05-19 21:45:43 +02:00
|
|
|
|
2017-02-07 17:51:43 +01:00
|
|
|
exports.protobuf = pbm
|
|
|
|
|
2016-09-13 13:23:11 +02:00
|
|
|
exports.hmac = c.hmac
|
|
|
|
exports.aes = c.aes
|
|
|
|
exports.webcrypto = c.webcrypto
|
2016-05-19 18:47:48 +02:00
|
|
|
|
2016-09-13 13:23:11 +02:00
|
|
|
const keys = exports.keys = require('./keys')
|
2017-02-04 04:23:38 -05:00
|
|
|
function isValidKeyType (keyType) {
|
|
|
|
const key = keys[keyType.toLowerCase()]
|
|
|
|
return key !== undefined
|
|
|
|
}
|
2016-12-23 08:52:40 -05:00
|
|
|
|
2016-05-19 22:33:09 +02:00
|
|
|
exports.keyStretcher = require('./key-stretcher')
|
|
|
|
exports.generateEphemeralKeyPair = require('./ephemeral-keys')
|
|
|
|
|
2016-05-19 18:47:48 +02:00
|
|
|
// Generates a keypair of the given type and bitsize
|
2016-09-13 13:23:11 +02:00
|
|
|
exports.generateKeyPair = (type, bits, cb) => {
|
2016-05-19 20:18:31 +02:00
|
|
|
let key = keys[type.toLowerCase()]
|
|
|
|
if (!key) {
|
2016-09-13 13:23:11 +02:00
|
|
|
return cb(new Error('invalid or unsupported key type'))
|
2016-05-19 18:47:48 +02:00
|
|
|
}
|
|
|
|
|
2016-09-13 13:23:11 +02:00
|
|
|
key.generateKeyPair(bits, cb)
|
2016-05-19 18:47:48 +02:00
|
|
|
}
|
|
|
|
|
2017-03-03 20:38:51 +00:00
|
|
|
// Generates a keypair of the given type and bitsize
|
|
|
|
// seed is a 32 byte uint8array
|
|
|
|
exports.generateKeyPairFromSeed = (type, seed, bits, cb) => {
|
|
|
|
let key = keys[type.toLowerCase()]
|
|
|
|
if (!key) {
|
|
|
|
return cb(new Error('invalid or unsupported key type'))
|
|
|
|
}
|
|
|
|
if (type.toLowerCase() !== 'ed25519') {
|
|
|
|
return cb(new Error('Seed key derivation is unimplemented for RSA or secp256k1'))
|
|
|
|
}
|
|
|
|
key.generateKeyPairFromSeed(seed, bits, cb)
|
|
|
|
}
|
|
|
|
|
2016-05-19 21:45:43 +02:00
|
|
|
// Converts a protobuf serialized public key into its
|
|
|
|
// representative object
|
|
|
|
exports.unmarshalPublicKey = (buf) => {
|
|
|
|
const decoded = pbm.PublicKey.decode(buf)
|
|
|
|
|
|
|
|
switch (decoded.Type) {
|
|
|
|
case pbm.KeyType.RSA:
|
|
|
|
return keys.rsa.unmarshalRsaPublicKey(decoded.Data)
|
2016-12-23 08:52:40 -05:00
|
|
|
case pbm.KeyType.Ed25519:
|
|
|
|
return keys.ed25519.unmarshalEd25519PublicKey(decoded.Data)
|
2017-02-04 04:23:38 -05:00
|
|
|
case pbm.KeyType.Secp256k1:
|
|
|
|
if (keys.secp256k1) {
|
|
|
|
return keys.secp256k1.unmarshalSecp256k1PublicKey(decoded.Data)
|
|
|
|
} else {
|
|
|
|
throw new Error('secp256k1 support requires libp2p-crypto-secp256k1 package')
|
|
|
|
}
|
2016-05-19 21:45:43 +02:00
|
|
|
default:
|
|
|
|
throw new Error('invalid or unsupported key type')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Converts a public key object into a protobuf serialized public key
|
|
|
|
exports.marshalPublicKey = (key, type) => {
|
|
|
|
type = (type || 'rsa').toLowerCase()
|
2017-02-04 04:23:38 -05:00
|
|
|
if (!isValidKeyType(type)) {
|
2016-05-19 21:45:43 +02:00
|
|
|
throw new Error('invalid or unsupported key type')
|
|
|
|
}
|
|
|
|
|
2016-09-13 13:23:11 +02:00
|
|
|
return key.bytes
|
2016-05-19 21:45:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Converts a protobuf serialized private key into its
|
|
|
|
// representative object
|
2016-09-13 13:23:11 +02:00
|
|
|
exports.unmarshalPrivateKey = (buf, callback) => {
|
2016-05-19 21:45:43 +02:00
|
|
|
const decoded = pbm.PrivateKey.decode(buf)
|
|
|
|
|
|
|
|
switch (decoded.Type) {
|
|
|
|
case pbm.KeyType.RSA:
|
2016-09-13 13:23:11 +02:00
|
|
|
return keys.rsa.unmarshalRsaPrivateKey(decoded.Data, callback)
|
2016-12-23 08:52:40 -05:00
|
|
|
case pbm.KeyType.Ed25519:
|
|
|
|
return keys.ed25519.unmarshalEd25519PrivateKey(decoded.Data, callback)
|
2017-02-04 04:23:38 -05:00
|
|
|
case pbm.KeyType.Secp256k1:
|
|
|
|
if (keys.secp256k1) {
|
|
|
|
return keys.secp256k1.unmarshalSecp256k1PrivateKey(decoded.Data, callback)
|
|
|
|
} else {
|
|
|
|
return callback(new Error('secp256k1 support requires libp2p-crypto-secp256k1 package'))
|
|
|
|
}
|
2016-05-19 21:45:43 +02:00
|
|
|
default:
|
2016-09-13 13:23:11 +02:00
|
|
|
callback(new Error('invalid or unsupported key type'))
|
2016-05-19 21:45:43 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Converts a private key object into a protobuf serialized private key
|
|
|
|
exports.marshalPrivateKey = (key, type) => {
|
|
|
|
type = (type || 'rsa').toLowerCase()
|
2017-02-04 04:23:38 -05:00
|
|
|
if (!isValidKeyType(type)) {
|
2016-05-19 21:45:43 +02:00
|
|
|
throw new Error('invalid or unsupported key type')
|
|
|
|
}
|
|
|
|
|
2016-09-13 13:23:11 +02:00
|
|
|
return key.bytes
|
2016-05-19 21:45:43 +02:00
|
|
|
}
|
2016-12-01 11:42:19 +00:00
|
|
|
|
|
|
|
exports.randomBytes = (number) => {
|
|
|
|
if (!number || typeof number !== 'number') {
|
|
|
|
throw new Error('first argument must be a Number bigger than 0')
|
|
|
|
}
|
2017-01-16 05:17:50 +01:00
|
|
|
|
|
|
|
return c.rsa.getRandomValues(new Uint8Array(number))
|
2016-12-01 11:42:19 +00:00
|
|
|
}
|