Files
bare-operating-system/packages/bare-os-openssh/vendor/bare-ssh2/shims/crypto/index.js
T
2026-04-08 20:12:29 -04:00

163 lines
5.0 KiB
JavaScript

'use strict'
const bareCrypto = require('bare-crypto')
const { Ber } = require('asn1')
const { Buffer: Asn1Buffer } = require('safer-buffer')
const { getCiphers, getHashes } = require('./lists.js')
const { wrapSign, wrapVerify } = require('./pem-ed25519.js')
const nextTick =
typeof queueMicrotask === 'function'
? (fn) => queueMicrotask(fn)
: (fn) => setTimeout(fn, 0)
/**
* Encode Ed25519 raw keys as SPKI / PKCS#8 DER (same layout as Node/OpenSSL RFC 8410),
* which bare-ssh2 `lib/keygen.js` parses via `convertKeys`.
*/
function ed25519RawToDer(pub32, privSeed32) {
const pub = Asn1Buffer.from(pub32)
const priv = Asn1Buffer.from(privSeed32)
const pubWriter = new Ber.Writer()
pubWriter.startSequence()
pubWriter.startSequence()
pubWriter.writeOID('1.3.101.112')
pubWriter.endSequence()
pubWriter.startSequence(Ber.BitString)
pubWriter.writeByte(0x00)
pubWriter._ensure(pub.length)
pubWriter._buf.set(pub, pubWriter._offset)
pubWriter._offset += pub.length
pubWriter.endSequence()
pubWriter.endSequence()
const privWriter = new Ber.Writer()
privWriter.startSequence()
privWriter.writeInt(0x00, Ber.Integer)
privWriter.startSequence()
privWriter.writeOID('1.3.101.112')
privWriter.endSequence()
privWriter.startSequence(Ber.OctetString)
privWriter.writeBuffer(priv, Ber.OctetString)
privWriter.endSequence()
privWriter.endSequence()
return { publicKey: pubWriter.buffer, privateKey: privWriter.buffer }
}
function generateKeyPairSyncBareEd25519(type, options) {
const pubEnc = (options && options.publicKeyEncoding) || {}
const privEnc = (options && options.privateKeyEncoding) || {}
if (
String(type).toLowerCase() !== 'ed25519' ||
pubEnc.type !== 'spki' ||
pubEnc.format !== 'der' ||
privEnc.type !== 'pkcs8' ||
privEnc.format !== 'der'
) {
throw new Error(
'Bare crypto shim: generateKeyPairSync only supports ed25519 with { spki, der } / { pkcs8, der } encodings'
)
}
const { publicKey, privateKey } = bareCrypto.generateKeyPair('ed25519')
const pubRaw = publicKey._key
const privRaw = privateKey._key
const pub32 = Asn1Buffer.from(pubRaw)
let priv32 = Asn1Buffer.from(privRaw)
if (priv32.length === 64) priv32 = Asn1Buffer.from(priv32.subarray(0, 32))
if (pub32.length !== 32 || priv32.length !== 32) {
throw new Error('Unexpected Ed25519 key material length from bare-crypto')
}
return ed25519RawToDer(pub32, priv32)
}
function generateKeyPairSync(type, options) {
if (typeof bareCrypto.generateKeyPairSync === 'function') {
return bareCrypto.generateKeyPairSync(type, options)
}
const t = String(type || '').toLowerCase()
if (t === 'x25519') {
const x = require('./x25519-compat.js')
if (options && Object.keys(options).length > 0) {
const pubEnc = options.publicKeyEncoding || {}
const privEnc = options.privateKeyEncoding || {}
if (
pubEnc.type !== 'spki' ||
pubEnc.format !== 'der' ||
privEnc.type !== 'pkcs8' ||
privEnc.format !== 'der'
) {
throw new Error(
'Bare crypto shim: x25519 generateKeyPairSync only supports default or spki/pkcs8 der'
)
}
}
return x.generateKeyPairSync()
}
if (t === 'ed25519') return generateKeyPairSyncBareEd25519(type, options)
throw new Error(`Bare crypto shim: generateKeyPairSync not supported for type ${type}`)
}
function generateKeyPair(type, options, callback) {
if (typeof options === 'function') {
callback = options
options = undefined
}
const native = bareCrypto.generateKeyPair
if (typeof callback === 'function') {
if (typeof native === 'function' && native.length >= 3) {
return native.call(bareCrypto, type, options, callback)
}
nextTick(() => {
try {
const pair = generateKeyPairSync(type, options)
callback(null, pair.publicKey, pair.privateKey)
} catch (err) {
callback(err)
}
})
return
}
if (typeof native === 'function') {
return native.call(bareCrypto, type, options)
}
}
function createPublicKey(descriptor) {
if (
descriptor &&
descriptor.type === 'spki' &&
descriptor.format === 'der' &&
descriptor.key
) {
return require('./x25519-compat.js').createPublicKeyFromSpkiDer(descriptor.key)
}
if (typeof bareCrypto.createPublicKey === 'function') {
return bareCrypto.createPublicKey(descriptor)
}
throw new Error('Bare crypto shim: createPublicKey only supports X25519 SPKI DER on Bare')
}
function diffieHellman(opts) {
return require('./x25519-compat.js').diffieHellman(opts)
}
function createECDH(curveName) {
throw new Error(
`Bare crypto shim: createECDH(${curveName}) is not implemented; bare-ssh2 should negotiate curve25519-sha256`
)
}
module.exports = Object.assign({}, bareCrypto, {
getCiphers,
getHashes,
generateKeyPairSync,
generateKeyPair,
createPublicKey,
diffieHellman,
createECDH,
sign: wrapSign(bareCrypto, bareCrypto.sign.bind(bareCrypto)),
verify: wrapVerify(bareCrypto, bareCrypto.verify.bind(bareCrypto))
})