Enumerator
This commit is contained in:
Родитель
294049bb26
Коммит
29449b2a9c
|
@ -0,0 +1,104 @@
|
|||
//
|
||||
// Enumerate system root CAs
|
||||
//
|
||||
var ref = require('ref')
|
||||
var ffi = require('ffi')
|
||||
var struct = require('ref-struct')
|
||||
var forge = require('node-forge')
|
||||
|
||||
var asn1 = forge.asn1
|
||||
var pki = forge.pki
|
||||
|
||||
var HCertStore = ref.refType(ref.types.void)
|
||||
|
||||
var Ctx = struct({
|
||||
dwCertEncodingType: 'long',
|
||||
pbCertEncoded: 'pointer',
|
||||
cbCertEncoded: 'long',
|
||||
pCertInfo: 'pointer',
|
||||
hCertStore: 'pointer'
|
||||
})
|
||||
|
||||
var pCtx = ref.refType(Ctx)
|
||||
|
||||
var crypt = ffi.Library('crypt32', {
|
||||
CertOpenSystemStoreA: [HCertStore, ['pointer', 'string']],
|
||||
CertCloseStore: ['int', [HCertStore, 'long']],
|
||||
CertEnumCertificatesInStore: [pCtx, [HCertStore, pCtx]]
|
||||
})
|
||||
|
||||
module.exports = me
|
||||
me.pki = pki
|
||||
|
||||
function me()
|
||||
{
|
||||
var listeners = []
|
||||
var errors = []
|
||||
var h, ctx = null
|
||||
|
||||
crypt.CertOpenSystemStoreA.async(null, 'ROOT', start)
|
||||
|
||||
return {on: handler}
|
||||
|
||||
function handler(name, cb)
|
||||
{
|
||||
switch(name)
|
||||
{
|
||||
case 'crt':
|
||||
listeners.push(cb)
|
||||
break
|
||||
case 'error':
|
||||
errors.push(cb)
|
||||
break
|
||||
default:
|
||||
croak(new Error('Unknown event: ' + name))
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
function free()
|
||||
{
|
||||
if(!h)
|
||||
return
|
||||
crypt.CertCloseStore.async(h, 0, function(){})
|
||||
h = 0
|
||||
}
|
||||
|
||||
function croak(err)
|
||||
{
|
||||
free()
|
||||
errors.forEach(function(cb){ cb(err) })
|
||||
}
|
||||
|
||||
function start(err, res)
|
||||
{
|
||||
if(err)
|
||||
return croak(err)
|
||||
h = res
|
||||
step()
|
||||
}
|
||||
|
||||
function step()
|
||||
{
|
||||
crypt.CertEnumCertificatesInStore.async(h, ctx, next)
|
||||
}
|
||||
|
||||
function next(err, res)
|
||||
{
|
||||
if(err)
|
||||
return croak(err)
|
||||
try {
|
||||
if(res.isNull())
|
||||
return free()
|
||||
ctx = res
|
||||
res = res.deref()
|
||||
res = res.pbCertEncoded.reinterpret(res.cbCertEncoded)
|
||||
res = asn1.fromDer(res.toString('binary'))
|
||||
res = pki.certificateFromAsn1(res)
|
||||
listeners.forEach(function(cb){ cb(res) })
|
||||
step()
|
||||
} catch (e) {
|
||||
croak(e)
|
||||
}
|
||||
}
|
||||
}
|
44
lib/index.js
44
lib/index.js
|
@ -1,38 +1,14 @@
|
|||
var fs = require('fs')
|
||||
var ref = require('ref')
|
||||
var ffi = require('ffi')
|
||||
var struct = require('ref-struct')
|
||||
var forge = require('node-forge')
|
||||
|
||||
var asn1 = forge.asn1
|
||||
var pki = forge.pki
|
||||
|
||||
var HCertStore = ref.refType(ref.types.void)
|
||||
|
||||
var Ctx = struct({
|
||||
dwCertEncodingType: 'long',
|
||||
pbCertEncoded: 'pointer',
|
||||
cbCertEncoded: 'long',
|
||||
pCertInfo: 'pointer',
|
||||
hCertStore: 'pointer'
|
||||
})
|
||||
|
||||
var pCtx = ref.refType(Ctx)
|
||||
|
||||
var crypt = ffi.Library('crypt32', {
|
||||
CertOpenSystemStoreA: [HCertStore, ['pointer', 'string']],
|
||||
CertCloseStore: ['int', [HCertStore, 'long']],
|
||||
CertEnumCertificatesInStore: [pCtx, [HCertStore, pCtx]]
|
||||
})
|
||||
|
||||
var h = crypt.CertOpenSystemStoreA(null, 'ROOT')
|
||||
var x = require('./enum')
|
||||
var n = 0
|
||||
for(var ctx = null; !(ctx = crypt.CertEnumCertificatesInStore(h, ctx)).isNull(); )
|
||||
|
||||
x()
|
||||
.on('error', function(err)
|
||||
{
|
||||
throw err
|
||||
})
|
||||
.on('crt', function(crt)
|
||||
{
|
||||
n++
|
||||
var z = ctx.deref()
|
||||
var asn = asn1.fromDer(z.pbCertEncoded.reinterpret(z.cbCertEncoded).toString('binary'))
|
||||
var crt = pki.certificateFromAsn1(asn)
|
||||
fs.writeFile('tmp/' + n + '.cer', pki.certificateToPem(crt))
|
||||
}
|
||||
crypt.CertCloseStore(h, 0)
|
||||
fs.writeFile('tmp/' + n + '.cer', x.pki.certificateToPem(crt))
|
||||
})
|
||||
|
|
Загрузка…
Ссылка в новой задаче