mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-06 00:13:33 +00:00
775 lines
38 KiB
JavaScript
775 lines
38 KiB
JavaScript
/*
|
|
Copyright 2018 Intel Corporation
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
var CRYPT_DECODE_NOCOPY_FLAG = 1;
|
|
var CERT_X500_NAME_STR = 3;
|
|
var CNG_RSA_PUBLIC_KEY_BLOB = 72;
|
|
var X509_CERT_TO_BE_SIGNED = 2;
|
|
var X509_CERT_REQUEST_TO_BE_SIGNED = 4;
|
|
var PROV_RSA_FULL = 1;
|
|
var CRYPT_MACHINE_KEYSET = 0x20;
|
|
var AT_SIGNATURE = 2;
|
|
var PKCS_7_ASN_ENCODING = 0x00010000;
|
|
var X509_ASN_ENCODING = 0x00000001;
|
|
var X509_DSS_PUBLICKEY = 38;
|
|
var X509_PUBLIC_KEY_INFO = 8;
|
|
var CERT_V1 = 0;
|
|
var CERT_V2 = 1;
|
|
var CERT_V3 = 2;
|
|
var BCRYPT_RNG_USE_ENTROPY_IN_BUFFER = 0x00000001;
|
|
var RSA_CSP_PUBLICKEYBLOB = 19;
|
|
|
|
var CRYPT_ALGORITHMS = {SHA1: "1.2.840.113549.1.1.5", SHA256: "1.2.840.113549.1.1.11", SHA384: "1.2.840.113549.1.1.12", SHA512: "1.2.840.113549.1.1.13"};
|
|
var CRYPT_ALGORITHMS_EX = { "1.2.840.113549.1.1.5": "SHA1", "1.2.840.113549.1.1.11": "SHA256", "1.2.840.113549.1.1.12": "SHA384", "1.2.840.113549.1.1.13": "SHA512" };
|
|
|
|
var CRYPT_EXTENSION_OIDS =
|
|
{
|
|
szOID_AUTHORITY_KEY_IDENTIFIER: "2.5.29.1",
|
|
szOID_KEY_ATTRIBUTES: "2.5.29.2",
|
|
szOID_CERT_POLICIES_95: "2.5.29.3",
|
|
szOID_KEY_USAGE_RESTRICTION: "2.5.29.4",
|
|
szOID_SUBJECT_ALT_NAME: "2.5.29.7",
|
|
szOID_ISSUER_ALT_NAME: "2.5.29.8",
|
|
szOID_BASIC_CONSTRAINTS: "2.5.29.10",
|
|
szOID_KEY_USAGE: "2.5.29.15",
|
|
szOID_PRIVATEKEY_USAGE_PERIOD: "2.5.29.16",
|
|
szOID_BASIC_CONSTRAINTS2: "2.5.29.19",
|
|
szOID_CERT_POLICIES: "2.5.29.32",
|
|
szOID_ANY_CERT_POLICY: "2.5.29.32.0",
|
|
szOID_INHIBIT_ANY_POLICY: "2.5.29.54",
|
|
szOID_AUTHORITY_KEY_IDENTIFIER2: "2.5.29.35",
|
|
szOID_SUBJECT_KEY_IDENTIFIER: "2.5.29.14",
|
|
szOID_SUBJECT_ALT_NAME2: "2.5.29.17",
|
|
szOID_ISSUER_ALT_NAME2: "2.5.29.18",
|
|
szOID_CRL_REASON_CODE: "2.5.29.21",
|
|
szOID_REASON_CODE_HOLD: "2.5.29.23",
|
|
szOID_CRL_DIST_POINTS: "2.5.29.31",
|
|
szOID_ENHANCED_KEY_USAGE: "2.5.29.37",
|
|
szOID_ANY_ENHANCED_KEY_USAGE: "2.5.29.37.0"
|
|
};
|
|
|
|
var CRYPT_KEY_ALGORITHMS =
|
|
{
|
|
"1.2.840.113549": "RSA",
|
|
"1.2.840.113549.1": "PKCS",
|
|
"1.2.840.113549.2": "RSA_HASH",
|
|
"1.2.840.113549.3": "RSA_ENCRYPT",
|
|
|
|
"1.2.840.113549.1.1": "PKCS_1",
|
|
"1.2.840.113549.1.2": "PKCS_2",
|
|
"1.2.840.113549.1.3": "PKCS_3",
|
|
"1.2.840.113549.1.4": "PKCS_4",
|
|
"1.2.840.113549.1.5": "PKCS_5",
|
|
"1.2.840.113549.1.6": "PKCS_6",
|
|
"1.2.840.113549.1.7": "PKCS_7",
|
|
"1.2.840.113549.1.8": "PKCS_8",
|
|
"1.2.840.113549.1.9": "PKCS_9",
|
|
"1.2.840.113549.1.10": "PKCS_10",
|
|
"1.2.840.113549.1.12": "PKCS_12",
|
|
|
|
"1.2.840.113549.1.1.1": "RSA_RSA",
|
|
"1.2.840.113549.1.1.2": "RSA_MD2RSA",
|
|
"1.2.840.113549.1.1.3": "RSA_MD4RSA",
|
|
"1.2.840.113549.1.1.4": "RSA_MD5RSA",
|
|
"1.2.840.113549.1.1.5": "RSA_SHA1RSA",
|
|
"1.2.840.113549.1.1.6": "RSA_SETOAEP_RSA",
|
|
|
|
"1.2.840.113549.1.1.7": "RSAES_OAEP",
|
|
"1.2.840.113549.1.1.8": "RSA_MGF1",
|
|
"1.2.840.113549.1.1.9": "RSA_PSPECIFIED",
|
|
"1.2.840.113549.1.1.10": "RSA_SSA_PSS",
|
|
"1.2.840.113549.1.1.11": "RSA_SHA256RSA",
|
|
"1.2.840.113549.1.1.12": "RSA_SHA384RSA",
|
|
"1.2.840.113549.1.1.13": "RSA_SHA512RSA",
|
|
"1.2.840.113549.1.3.1": "RSA_DH"
|
|
};
|
|
|
|
var CRYPT_KEY_USAGES =
|
|
{
|
|
CERT_DIGITAL_SIGNATURE_KEY_USAGE: 0x80,
|
|
CERT_NON_REPUDIATION_KEY_USAGE: 0x40,
|
|
CERT_KEY_ENCIPHERMENT_KEY_USAGE: 0x20,
|
|
CERT_DATA_ENCIPHERMENT_KEY_USAGE: 0x10,
|
|
CERT_KEY_AGREEMENT_KEY_USAGE: 0x08,
|
|
CERT_KEY_CERT_SIGN_KEY_USAGE: 0x04,
|
|
CERT_OFFLINE_CRL_SIGN_KEY_USAGE: 0x02,
|
|
CERT_CRL_SIGN_KEY_USAGE: 0x02,
|
|
CERT_ENCIPHER_ONLY_KEY_USAGE: 0x01
|
|
};
|
|
|
|
function WinCrypto()
|
|
{
|
|
this._ObjectID = 'win-crypto';
|
|
this._marshal = require('_GenericMarshal');
|
|
this._Kernel32 = this._marshal.CreateNativeProxy('Kernel32.dll');
|
|
this._Kernel32.CreateMethod('FileTimeToSystemTime');
|
|
this._Kernel32.CreateMethod('SystemTimeToFileTime');
|
|
this._Kernel32.CreateMethod('GetLastError');
|
|
this._Kernel32.CreateMethod('GetSystemTime');
|
|
|
|
this._Bcrypt = this._marshal.CreateNativeProxy('Bcrypt.dll');
|
|
this._Bcrypt.CreateMethod('BCryptGenRandom');
|
|
this._Bcrypt.CreateMethod('BCryptCloseAlgorithmProvider');
|
|
this._Bcrypt.CreateMethod('BCryptOpenAlgorithmProvider');
|
|
|
|
this._Crypt32 = this._marshal.CreateNativeProxy('Crypt32.dll');
|
|
this._Crypt32.CreateMethod('CertStrToNameA');
|
|
this._Crypt32.CreateMethod('CertCreateCertificateContext');
|
|
this._Crypt32.CreateMethod('CertCreateSelfSignCertificate');
|
|
this._Crypt32.CreateMethod('CryptAcquireCertificatePrivateKey');
|
|
this._Crypt32.CreateMethod('CryptDecodeObject');
|
|
this._Crypt32.CreateMethod('CryptDecodeObjectEx');
|
|
this._Crypt32.CreateMethod('CryptEncodeObject');
|
|
this._Crypt32.CreateMethod('CryptHashCertificate');
|
|
this._Crypt32.CreateMethod('CryptSignMessage');
|
|
this._Crypt32.CreateMethod('CryptSignAndEncodeCertificate');
|
|
this._Crypt32.CreateMethod('CryptStringToBinaryA');
|
|
this._Crypt32.CreateMethod('CryptVerifyMessageSignature');
|
|
this.CRYPT_KEY_ALGORITHMS_OIDS = {};
|
|
for(var i in CRYPT_KEY_ALGORITHMS)
|
|
{
|
|
this.CRYPT_KEY_ALGORITHMS_OIDS[CRYPT_KEY_ALGORITHMS[i]] = i;
|
|
}
|
|
this.CRYPT_ENHANCED_KEY_USAGES =
|
|
{
|
|
CLIENT_AUTH: '1.3.6.1.5.5.7.3.2',
|
|
SERVER_AUTH: '1.3.6.1.5.5.7.3.1'
|
|
};
|
|
|
|
this.X509_ASN_ENCODING = 0x00000001;
|
|
this.PKCS_7_ASN_ENCODING = 0x00010000;
|
|
this.BCRYPT_RNG_ALGORITHM = this._marshal.CreateVariable('RNG', { wide: true });
|
|
|
|
this.createKeyRestriction = function createKeyRestriction()
|
|
{
|
|
var retVal =
|
|
{
|
|
CERT_DATA_ENCIPHERMENT_KEY_USAGE: false,
|
|
CERT_DIGITAL_SIGNATURE_KEY_USAGE: false,
|
|
CERT_KEY_AGREEMENT_KEY_USAGE: false,
|
|
CERT_KEY_CERT_SIGN_KEY_USAGE: false,
|
|
CERT_KEY_ENCIPHERMENT_KEY_USAGE: false,
|
|
CERT_NON_REPUDIATION_KEY_USAGE: false,
|
|
CERT_OFFLINE_CRL_SIGN_KEY_USAGE: false
|
|
}
|
|
return (retVal);
|
|
}
|
|
|
|
this.makeCert = function makeCert(options)
|
|
{
|
|
if (!options._algorithm || !CRYPT_ALGORITHMS[options._algorithm]) { throw ('Invalid Algorithm specified: ' + options._algorithm); }
|
|
var extensions = [];
|
|
var ext = null;
|
|
|
|
// CN => Common Name
|
|
// T => Title
|
|
// L => Locality Name
|
|
// O => Organization Name
|
|
// C => Country
|
|
// S => State or Province
|
|
// STREET => Street Address
|
|
|
|
var inStr = '';
|
|
var delimiter = '';
|
|
|
|
for(var i in options)
|
|
{
|
|
if (!i.startsWith('_'))
|
|
{
|
|
inStr += (delimiter + i + '=' + options[i]);
|
|
if (delimiter == '') { delimiter = ', '; }
|
|
}
|
|
}
|
|
console.log('Certificate Options: ' + inStr);
|
|
|
|
// Check Extensions
|
|
if (options._keyRestrictions)
|
|
{
|
|
var restrictions = this._marshal.CreateVariable(1);
|
|
restrictions.byte = restrictions.toBuffer()[0];
|
|
for(var i in options._keyRestrictions)
|
|
{
|
|
if (options._keyRestrictions[i] == true && CRYPT_KEY_USAGES[i]) { restrictions.byte |= CRYPT_KEY_USAGES[i]; }
|
|
}
|
|
if (restrictions.byte != 0)
|
|
{
|
|
var restrictionInfo = this._marshal.CreateVariable(this._marshal.PointerSize == 4 ? 20 : 40);
|
|
if(this._marshal.PointerSize == 4)
|
|
{
|
|
restrictionInfo.Deref(8, 4).toBuffer().writeUInt32LE(1);
|
|
restrictions.pointerBuffer().copy(restrictionInfo.Deref(12, 4).toBuffer());
|
|
}
|
|
else
|
|
{
|
|
restrictionInfo.Deref(16, 4).toBuffer().writeUInt32LE(1);
|
|
restrictions.pointerBuffer().copy(restrictionInfo.Deref(24, 8).toBuffer());
|
|
}
|
|
var encodedObject = this.CryptEncodeObject(this.X509_ASN_ENCODING, CRYPT_EXTENSION_OIDS.szOID_KEY_USAGE_RESTRICTION, restrictionInfo);
|
|
encodedObject.oid = CRYPT_EXTENSION_OIDS.szOID_KEY_USAGE_RESTRICTION;
|
|
extensions.push(encodedObject);
|
|
}
|
|
}
|
|
if (extensions.length > 0)
|
|
{
|
|
ext = this._marshal.CreateVariable(this._marshal.PointerSize == 4 ? (16 * extensions.length) : (32 * extensions.length));
|
|
ext.stor = [];
|
|
for(var i in extensions)
|
|
{
|
|
var oid = this._marshal.CreateVariable(extensions[i].oid); ext.stor.push(oid);
|
|
var x = this._marshal.PointerSize == 4 ? (16 * i) : (32 * i);
|
|
oid.pointerBuffer().copy(ext.Deref(x, this._marshal.PointerSize).toBuffer());
|
|
|
|
ext.Deref(x + this._marshal.PointerSize, 4).toBuffer().writeUInt32LE(1);
|
|
ext.Deref(x + this._marshal.PointerSize == 4 ? 8 : 16, 4).toBuffer().writeUInt32LE(extensions[i]._size);
|
|
extensions[i].pointerBuffer().copy(ext.Deref(x + this._marshal.PointerSize == 4 ? 12 : 24, this._marshal.PointerSize).toBuffer());
|
|
}
|
|
|
|
var extContainer = this._marshal.CreateVariable(this._marshal.PointerSize == 4 ? 8 : 16);
|
|
extContainer.Deref(0, 4).toBuffer().writeUInt32LE(extensions.length);
|
|
ext.pointerBuffer().copy(extContainer.Deref(this._marshal.PointerSize, this._marshal.PointerSize).toBuffer());
|
|
extContainer.ext = ext;
|
|
ext = extContainer;
|
|
}
|
|
|
|
var pszX500 = this._marshal.CreateVariable(inStr);
|
|
var cbEncoded = this._marshal.CreateVariable(4);
|
|
var pbEncoded = 0;
|
|
|
|
cbEncoded.toBuffer().writeUInt32LE(0);
|
|
if(this._Crypt32.CertStrToNameA(X509_ASN_ENCODING, pszX500, CERT_X500_NAME_STR, 0, pbEncoded, cbEncoded, 0).Val == 0)
|
|
{
|
|
throw ("Error calling 'CertStrToName', Error Code = " + this._Kernel32.GetLastError().Val);
|
|
}
|
|
|
|
pbEncoded = this._marshal.CreateVariable(cbEncoded.toBuffer().readUInt32LE());
|
|
if (this._Crypt32.CertStrToNameA(X509_ASN_ENCODING, pszX500, CERT_X500_NAME_STR, 0, pbEncoded, cbEncoded, 0).Val == 0)
|
|
{
|
|
throw ("Error calling 'CertStrToName', Error Code = " + this._Kernel32.GetLastError().Val);
|
|
}
|
|
|
|
var blob = this._marshal.CreateVariable(this._marshal.PointerSize == 4 ? 8 : 16);
|
|
blob.toBuffer().writeUInt32LE(cbEncoded.toBuffer().readUInt32LE(), 0);
|
|
pbEncoded.pointerBuffer().copy(blob.toBuffer(), this._marshal.PointerSize);
|
|
|
|
var keyProvider = this._marshal.CreateVariable(this._marshal.PointerSize == 4 ? 28 : 48);
|
|
var containerName = this._marshal.CreateVariable(options.CN, { wide: true });
|
|
|
|
containerName.pointerBuffer().copy(keyProvider.toBuffer());
|
|
keyProvider.toBuffer().writeUInt32LE(PROV_RSA_FULL, this._marshal.PointerSize == 4 ? 8 : 16);
|
|
keyProvider.toBuffer().writeUInt32LE(CRYPT_MACHINE_KEYSET, this._marshal.PointerSize == 4 ? 12 : 20);
|
|
keyProvider.toBuffer().writeUInt32LE(AT_SIGNATURE, this._marshal.PointerSize == 4 ? 24 : 40);
|
|
var cryptAlgorithm = this._marshal.CreateVariable(this._marshal.PointerSize == 4 ? 12 : 24);
|
|
var algo = this._marshal.CreateVariable(CRYPT_ALGORITHMS[options._algorithm]);
|
|
algo.pointerBuffer().copy(cryptAlgorithm.toBuffer());
|
|
|
|
var expiration = this._marshal.CreateVariable(16);
|
|
this._Kernel32.GetSystemTime(expiration);
|
|
|
|
// If today is Feb-29, change the expiration to Feb-28, because that's simpler than dealing with leap-year exception complexity
|
|
if (expiration.toBuffer().readUInt16LE(2) == 2 && expiration.toBuffer().readUInt16LE(6) == 29) { exipiration.toBuffer().writeUInt16LE(28, 6); }
|
|
var year = expiration.toBuffer().readUInt16LE(0);
|
|
year += options._years;
|
|
expiration.toBuffer().writeUInt16LE(year, 0);
|
|
|
|
var pCert = this._Crypt32.CertCreateSelfSignCertificate(0, blob, 0, keyProvider, cryptAlgorithm, 0, expiration, ext ? ext : 0);
|
|
if (pCert.Val == 0) {
|
|
console.log('Error Code = ' + this._Kernel32.GetLastError().Val);
|
|
}
|
|
console.log('pCert = ' + pCert.Val);
|
|
|
|
var privateKey = this._marshal.CreatePointer();
|
|
var keyspec = this._marshal.CreateVariable(4);
|
|
var needFree = this._marshal.CreateVariable(4);
|
|
|
|
if(pCert.Val != 0)
|
|
{
|
|
var keyResult = this._Crypt32.CryptAcquireCertificatePrivateKey(pCert, 0, 0, privateKey, keyspec, needFree);
|
|
pCert.privateKey = privateKey.Deref();
|
|
pCert.privateKey.keySpec = keyspec.toBuffer().readUInt32LE();
|
|
pCert.privateKey.needFree = needFree.toBuffer().readUInt32LE();
|
|
console.log('keyResult=' + keyResult.Val);
|
|
console.log('NeedFree=' + needFree.toBuffer().readUInt32LE());
|
|
console.log('KeySpec=' + keyspec.toBuffer().readUInt32LE());
|
|
|
|
|
|
var certInfo = pCert.Deref(this._marshal.PointerSize == 4 ? 12 : 24, this._marshal.PointerSize).Deref(this._marshal.PointerSize == 4 ? 112 : 208);
|
|
var signatureAlgorithm = certInfo.Deref(this._marshal.PointerSize == 4 ? 12 : 24, this._marshal.PointerSize);
|
|
var publicKeyInfo = certInfo.Deref(this._marshal.PointerSize == 4 ? 56 : 96, this._marshal.PointerSize == 4 ? 24 : 48);
|
|
var keyAlgorithm = publicKeyInfo.Deref(0, this._marshal.PointerSize == 4 ? 12 : 24);
|
|
var keyLen = publicKeyInfo.Deref(this._marshal.PointerSize == 4 ? 12 : 16, 4).toBuffer().readUInt32LE();
|
|
|
|
var key = publicKeyInfo.Deref(this._marshal.PointerSize == 4 ? 16 : 32, this._marshal.PointerSize).Deref(keyLen);
|
|
pCert.publicKey = key.toBuffer();
|
|
pCert.publicKey._key = key;
|
|
pCert.publicKey.oid = keyAlgorithm.Deref().String;
|
|
pCert.SubjectPublicKeyInfo = publicKeyInfo;
|
|
pCert.Subject = certInfo.Deref(this._marshal.PointerSize == 4 ? 48 : 80, this._marshal.PointerSize == 4 ? 112 : 208);
|
|
console.log('PublicKey/OID: ' + pCert.publicKey.oid);
|
|
}
|
|
pCert.parent = this;
|
|
pCert.signMessage = function signMessage(message, options)
|
|
{
|
|
var crypto = this.parent;
|
|
var signMessagePara = crypto._marshal.CreateVariable(crypto._marshal.PointerSize == 4 ? 68 : 120);
|
|
var cbSize = signMessagePara.Deref(0, 4);
|
|
var msgEncodingType = signMessagePara.Deref(4, 4);
|
|
var pcertContext = signMessagePara.Deref(8, crypto._marshal.PointerSize);
|
|
var hashAlgorithm = signMessagePara.Deref(crypto._marshal.PointerSize == 4 ? 12 : 16, crypto._marshal.PointerSize == 4 ? 12 : 24);
|
|
var cMsgCert = signMessagePara.Deref(crypto._marshal.PointerSize == 4 ? 28 : 48, 4);
|
|
var rgpMsgCert = signMessagePara.Deref(crypto._marshal.PointerSize == 4 ? 32 : 56, crypto._marshal.PointerSize);
|
|
var algorithm = crypto._marshal.CreateVariable(CRYPT_ALGORITHMS[options.hashAlgorithm]);
|
|
|
|
var msgArray = crypto._marshal.CreateVariable(message.length);
|
|
var rgcbToBeSigned = crypto._marshal.CreateVariable(4);
|
|
var signedMessage;
|
|
var signedMessageLen = crypto._marshal.CreateVariable(4);
|
|
signedMessageLen.toBuffer().writeUInt32LE(0);
|
|
|
|
rgcbToBeSigned.toBuffer().writeUInt32LE(message.length);
|
|
message.copy(msgArray.toBuffer());
|
|
|
|
algorithm.pointerBuffer().copy(hashAlgorithm.toBuffer());
|
|
msgEncodingType.toBuffer().writeUInt32LE(options.encodingType);
|
|
|
|
cbSize.toBuffer().writeUInt32LE(crypto._marshal.PointerSize == 4 ? 68 : 120);
|
|
msgEncodingType.toBuffer().writeUInt32LE(PKCS_7_ASN_ENCODING);
|
|
this.pointerBuffer().copy(pcertContext.toBuffer());
|
|
cMsgCert.toBuffer().writeUInt32LE(1);
|
|
pcertContext.getPointerPointer().toBuffer().copy(rgpMsgCert.toBuffer());
|
|
|
|
var result = crypto._Crypt32.CryptSignMessage(signMessagePara, 0, 1, msgArray.getPointerPointer(), rgcbToBeSigned, 0, signedMessageLen).Val;
|
|
if (result != 0)
|
|
{
|
|
signedMessage = crypto._marshal.CreateVariable(signedMessageLen.toBuffer().readUInt32LE());
|
|
if(crypto._Crypt32.CryptSignMessage(signMessagePara, 0, 1, msgArray.getPointerPointer(), rgcbToBeSigned, signedMessage, signedMessageLen).Val != 0)
|
|
{
|
|
var retVal = signedMessage.toBuffer();
|
|
retVal._owner = signedMessage;
|
|
return (retVal);
|
|
}
|
|
else
|
|
{
|
|
throw ('Error Signing Message: ' + crypto._Kernel32.GetLastError().Val);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw ('Error Signing Message: ' + crypto._Kernel32.GetLastError().Val);
|
|
}
|
|
};
|
|
return (pCert);
|
|
};
|
|
this.verifyMessage = function verifyMessage(message, options)
|
|
{
|
|
var verifyParam = this._marshal.CreateVariable(this._marshal.PointerSize == 4 ? 20 : 32);
|
|
var _cbSize = verifyParam.Deref(0, 4);
|
|
var _dwMsgAndCertEncodingType = verifyParam.Deref(4, 4);
|
|
var signedMessage = this._marshal.CreateVariable(message.length);
|
|
message.copy(signedMessage.toBuffer());
|
|
var decodedLength = this._marshal.CreateVariable(4);
|
|
decodedLength.toBuffer().writeUInt32LE(0);
|
|
|
|
_cbSize.toBuffer().writeUInt32LE(this._marshal.PointerSize == 4 ? 20 : 32);
|
|
_dwMsgAndCertEncodingType.toBuffer().writeUInt32LE(options.encodingType);
|
|
|
|
var result = this._Crypt32.CryptVerifyMessageSignature(verifyParam, 0, signedMessage, message.length, 0, decodedLength, 0).Val;
|
|
if(result != 0)
|
|
{
|
|
var signerCert = this._marshal.CreatePointer();
|
|
var decoded = this._marshal.CreateVariable(decodedLength.toBuffer().readUInt32LE());
|
|
console.log('Decoded Length = ' + decodedLength.toBuffer().readUInt32LE());
|
|
|
|
if (this._Crypt32.CryptVerifyMessageSignature(verifyParam, 0, signedMessage, message.length, decoded, decodedLength, 0).Val != 0)
|
|
{
|
|
var retVal = decoded.toBuffer();
|
|
retVal._owner = decoded;
|
|
return (retVal);
|
|
}
|
|
else
|
|
{
|
|
throw ('Error Verifying Message: ' + this._Kernel32.GetLastError().Val);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw ('Error Verifying Message2');
|
|
}
|
|
};
|
|
this.loadCert = function loadCert(encodedCert, options)
|
|
{
|
|
console.log('LoadCert: ' + options.encodingType, 'Length: ' + encodedCert.length);
|
|
var pbCertEncoded = this._marshal.CreateVariable(encodedCert.length);
|
|
encodedCert.copy(pbCertEncoded.toBuffer());
|
|
|
|
var pcert = this._Crypt32.CertCreateCertificateContext(options.encodingType, pbCertEncoded, encodedCert.length);
|
|
if(pcert.Val == 0)
|
|
{
|
|
throw ('Error loading Certificate: ' + this._Kernel32.GetLastError().Val);
|
|
}
|
|
else
|
|
{
|
|
pcert._marshal = this._marshal;
|
|
pcert._Crypt32 = this._Crypt32;
|
|
pcert._Kernel32 = this._Kernel32;
|
|
pcert._raw = pbCertEncoded;
|
|
pcert.getInfo = getInfo;
|
|
return (pcert);
|
|
}
|
|
};
|
|
this.EncodeString = function EncodeString(inStr)
|
|
{
|
|
var pszX500 = this._marshal.CreateVariable(inStr);
|
|
var dwSize = this._marshal.CreateVariable(4);
|
|
dwSize.toBuffer().writeUInt32LE(0);
|
|
|
|
if (this._Crypt32.CertStrToNameA(X509_ASN_ENCODING, pszX500, CERT_X500_NAME_STR, 0, 0, dwSize, 0).Val == 0)
|
|
{
|
|
throw ("Error calling 'CertStrToName', Error Code = " + this._Kernel32.GetLastError().Val);
|
|
}
|
|
var pbEncoded = this._marshal.CreateVariable(dwSize.toBuffer().readUInt32LE());
|
|
if (this._Crypt32.CertStrToNameA(X509_ASN_ENCODING, pszX500, CERT_X500_NAME_STR, 0, pbEncoded, dwSize, 0).Val == 0)
|
|
{
|
|
throw ("Error calling 'CertStrToName', Error Code = " + this._Kernel32.GetLastError().Val);
|
|
}
|
|
pbEncoded._size = dwSize.toBuffer().readUInt32LE();
|
|
return (pbEncoded);
|
|
};
|
|
this.CryptEncodeObject = function CryptEncodeObject(encodingType, structType, data)
|
|
{
|
|
var dwBufferSize = this._marshal.CreateVariable(4);
|
|
var stype = typeof (structType) == 'number' ? structType : this._marshal.CreateVariable(structType);
|
|
|
|
if(this._Crypt32.CryptEncodeObject(encodingType, stype, data, 0, dwBufferSize).Val == 0)
|
|
{
|
|
throw ('Error Calling CryptEncodeObject (' + this._Kernel32.GetLastError().Val + ')');
|
|
}
|
|
|
|
var outData = this._marshal.CreateVariable(dwBufferSize.toBuffer().readUInt32LE());
|
|
if (this._Crypt32.CryptEncodeObject(encodingType, stype, data, outData, dwBufferSize).Val == 0)
|
|
{
|
|
throw ('Error Calling CryptEncodeObject (' + this._Kernel32.GetLastError().Val + ')');
|
|
}
|
|
outData._size = dwBufferSize.toBuffer().readUInt32LE();
|
|
return (outData);
|
|
}
|
|
this.MakeCertFromPublicKey = function MakeCertFromPublicKey(options)
|
|
{
|
|
if (!options.Issuer || !options.Subject || !options.PublicKey || !options.SigningCert || !options.SignatureAlgorithm) { throw ('Missing Parameters: Issuer, Subject, PublicKey, SigningCert, SignatureAlgorithm'); }
|
|
var extensions = [];
|
|
var certinfo = this._marshal.CreateVariable(this._marshal.PointerSize == 4 ? 112 : 208);
|
|
certinfo.Deref(0, 4).toBuffer().writeUInt32LE(CERT_V3);
|
|
var provider = this._marshal.CreatePointer();
|
|
var r = this._Bcrypt.BCryptOpenAlgorithmProvider(provider, this.BCRYPT_RNG_ALGORITHM, 0, 0).Val;
|
|
|
|
if (r != 0)
|
|
{
|
|
throw('Error opening RandomNumberGenerator')
|
|
}
|
|
var serial = this._marshal.CreateVariable(8);
|
|
r = this._Bcrypt.BCryptGenRandom(provider.Deref(), serial, serial._size, BCRYPT_RNG_USE_ENTROPY_IN_BUFFER).Val;
|
|
r = this._Bcrypt.BCryptCloseAlgorithmProvider(provider.Deref(), 0).Val;
|
|
|
|
|
|
// SerialNumber
|
|
certinfo.Deref(this._marshal.PointerSize == 4 ? 4 : 8, 4).toBuffer().writeUInt32LE(serial._size);
|
|
serial.pointerBuffer().copy(certinfo.Deref(this._marshal.PointerSize == 4 ? 8 : 16, this._marshal.PointerSize).toBuffer());
|
|
certinfo._serial = serial;
|
|
|
|
// Signature Algorithm
|
|
certinfo._SignatureAlgorithm = certinfo.Deref(this._marshal.PointerSize == 4 ? 12 : 24, this._marshal.PointerSize == 4 ? 12 : 24);
|
|
certinfo._SignatureAlgorithm.oid = this._marshal.CreateVariable(options.SignatureAlgorithm);
|
|
certinfo._SignatureAlgorithm.oid.pointerBuffer().copy(certinfo._SignatureAlgorithm.Deref(0, this._marshal.PointerSize).toBuffer());
|
|
|
|
// Issuer
|
|
certinfo._Issuer_Unencoded = this._marshal.CreateVariable(options.Issuer);
|
|
certinfo._Issuer_encodedSize = this._marshal.CreateVariable(4);
|
|
if (this._Crypt32.CertStrToNameA(X509_ASN_ENCODING, certinfo._Issuer_Unencoded, CERT_X500_NAME_STR, 0, 0, certinfo._Issuer_encodedSize, 0).Val == 0) { throw ('Error Calling CertStrToName'); }
|
|
certinfo._Issuer_encoded = this._marshal.CreateVariable(certinfo._Issuer_encodedSize.toBuffer().readUInt32LE());
|
|
if (this._Crypt32.CertStrToNameA(X509_ASN_ENCODING, certinfo._Issuer_Unencoded, CERT_X500_NAME_STR, 0, certinfo._Issuer_encoded, certinfo._Issuer_encodedSize, 0).Val == 0) { throw ('Error Calling CertStrToName'); }
|
|
certinfo._Issuer_encoded._size = certinfo._Issuer_encodedSize.toBuffer().readUInt32LE();
|
|
|
|
certinfo.Deref(this._marshal.PointerSize == 4 ? 24 : 48, 4).toBuffer().writeUInt32LE(certinfo._Issuer_encoded._size);
|
|
certinfo._Issuer_encoded.pointerBuffer().copy(certinfo.Deref(this._marshal.PointerSize == 4 ? 28 : 56, this._marshal.PointerSize).toBuffer());
|
|
|
|
// Subject
|
|
var delimiter = '';
|
|
var inStr = '';
|
|
for (var i in options.Subject)
|
|
{
|
|
inStr += (delimiter + i + '=' + options.Subject[i]);
|
|
if (delimiter == '') { delimiter = ', '; }
|
|
}
|
|
|
|
var pszX500 = this._marshal.CreateVariable(inStr);
|
|
var cbEncoded = this._marshal.CreateVariable(4);
|
|
var pbEncoded = 0;
|
|
cbEncoded.toBuffer().writeUInt32LE(0);
|
|
if (this._Crypt32.CertStrToNameA(X509_ASN_ENCODING, pszX500, CERT_X500_NAME_STR, 0, pbEncoded, cbEncoded, 0).Val == 0)
|
|
{
|
|
throw ("Error calling 'CertStrToName', Error Code = " + this._Kernel32.GetLastError().Val);
|
|
}
|
|
pbEncoded = this._marshal.CreateVariable(cbEncoded.toBuffer().readUInt32LE());
|
|
if (this._Crypt32.CertStrToNameA(X509_ASN_ENCODING, pszX500, CERT_X500_NAME_STR, 0, pbEncoded, cbEncoded, 0).Val == 0)
|
|
{
|
|
throw ("Error calling 'CertStrToName', Error Code = " + this._Kernel32.GetLastError().Val);
|
|
}
|
|
pbEncoded._size = cbEncoded.toBuffer().readUInt32LE();
|
|
|
|
certinfo._Subject = pbEncoded;
|
|
certinfo.Deref(this._marshal.PointerSize == 4 ? 48 : 80, 4).toBuffer().writeUInt32LE(pbEncoded._size);
|
|
pbEncoded.pointerBuffer().copy(certinfo.Deref(this._marshal.PointerSize == 4 ? 52 : 88, this._marshal.PointerSize).toBuffer());
|
|
|
|
// SubjectPublicKeyInfo
|
|
certinfo._pkinfo = certinfo.Deref(this._marshal.PointerSize == 4 ? 56 : 96, this._marshal.PointerSize == 4 ? 24 : 48);
|
|
certinfo._pkinfo._oid = this._marshal.CreateVariable(options.PublicKey.oid);
|
|
certinfo._pkinfo._oid.pointerBuffer().copy(certinfo._pkinfo.Deref(0, this._marshal.PointerSize).toBuffer());
|
|
certinfo._pkinfo.Deref(this._marshal.PointerSize == 4 ? 12 : 24, 4).toBuffer().writeUInt32LE(options.PublicKey.length);
|
|
certinfo._pkinfo._key = this._marshal.CreateVariable(options.PublicKey.length);
|
|
options.PublicKey.copy(certinfo._pkinfo._key.toBuffer());
|
|
certinfo._pkinfo._key.pointerBuffer().copy(certinfo._pkinfo.Deref(this._marshal.PointerSize == 4 ? 16 : 32, this._marshal.PointerSize).toBuffer());
|
|
|
|
var ft_notBefore_dt = new Date(); ft_notBefore_dt.setTime(Date.now() - 3600000); // One Hour Ago
|
|
var ft_notBefore = this.dateToFileTime(ft_notBefore_dt);
|
|
ft_notBefore.toBuffer().copy(certinfo.Deref(this._marshal.PointerSize == 4 ? 32 : 64, 8).toBuffer());
|
|
|
|
var ft_notAfter_dt = new Date(); ft_notAfter_dt.setTime(Date.now() + (365 * 24 * 60 * 60 * 1000)); // One Year from now
|
|
var ft_notAfter = this.dateToFileTime(ft_notAfter_dt);
|
|
ft_notAfter.toBuffer().copy(certinfo.Deref(this._marshal.PointerSize == 4 ? 40 : 72, 8).toBuffer());
|
|
|
|
// Parse Extensions
|
|
if (options.KeyUsage)
|
|
{
|
|
var restrictionInfo = this._marshal.CreateVariable(this._marshal.PointerSize == 4 ? 20 : 40);
|
|
restrictionInfo.bitBlob = this._marshal.CreateVariable(1);
|
|
var b = 0;
|
|
for (var i in options.KeyUsage)
|
|
{
|
|
if (CRYPT_KEY_USAGES[options.KeyUsage[i]]) { b |= CRYPT_KEY_USAGES[options.KeyUsage[i]]; }
|
|
}
|
|
restrictionInfo.bitBlob.toBuffer()[0] = b;
|
|
|
|
if (this._marshal.PointerSize == 4)
|
|
{
|
|
restrictionInfo.Deref(8, 4).toBuffer().writeUInt32LE(restrictionInfo.bitBlob._size);
|
|
restrictionInfo.bitBlob.pointerBuffer().copy(restrictionInfo.Deref(12, 4).toBuffer());
|
|
}
|
|
else
|
|
{
|
|
restrictionInfo.Deref(16, 4).toBuffer().writeUInt32LE(restrictionInfo.bitBlob._size);
|
|
restrictionInfo.bitBlob.pointerBuffer().copy(restrictionInfo.Deref(24, 8).toBuffer());
|
|
}
|
|
|
|
restrictionInfo.encodedObject = this.CryptEncodeObject(this.X509_ASN_ENCODING, CRYPT_EXTENSION_OIDS.szOID_KEY_USAGE_RESTRICTION, restrictionInfo);
|
|
restrictionInfo.encodedObject.oid = CRYPT_EXTENSION_OIDS.szOID_KEY_USAGE_RESTRICTION;
|
|
restrictionInfo.encodedObject.ri = restrictionInfo;
|
|
extensions.push(restrictionInfo.encodedObject);
|
|
}
|
|
if (options.EnhancedKeyUsages)
|
|
{
|
|
var eku = this._marshal.CreateVariable(this._marshal.PointerSize == 4 ? 8 : 16);
|
|
eku.Deref(0, 4).toBuffer().writeUInt32LE(options.EnhancedKeyUsages.length); // cUsageIdentifier
|
|
|
|
eku._array = this._marshal.CreateVariable(options.EnhancedKeyUsages.length * this._marshal.PointerSize);
|
|
for(var i in options.EnhancedKeyUsages)
|
|
{
|
|
eku._array[i] = this._marshal.CreateVariable(options.EnhancedKeyUsages[i]);
|
|
eku._array[i].pointerBuffer().copy(eku._array.Deref(i * this._marshal.PointerSize, this._marshal.PointerSize).toBuffer());
|
|
}
|
|
|
|
eku._array.pointerBuffer().copy(eku.Deref(this._marshal.PointerSize, this._marshal.PointerSize).toBuffer()); //rgpszUsageIdentifier
|
|
eku.oid = CRYPT_EXTENSION_OIDS.szOID_ENHANCED_KEY_USAGE;
|
|
|
|
eku.encodedObject = this.CryptEncodeObject(this.X509_ASN_ENCODING, CRYPT_EXTENSION_OIDS.szOID_ENHANCED_KEY_USAGE, eku);
|
|
eku.encodedObject.oid = CRYPT_EXTENSION_OIDS.szOID_ENHANCED_KEY_USAGE;
|
|
eku.encodedObject.eku = eku;
|
|
extensions.push(eku.encodedObject);
|
|
}
|
|
|
|
|
|
// Add Extensions
|
|
if (extensions.length > 0)
|
|
{
|
|
var ext = this._marshal.CreateVariable(this._marshal.PointerSize == 4 ? (16 * extensions.length) : (32 * extensions.length));
|
|
ext.stor = [];
|
|
for (var i in extensions)
|
|
{
|
|
var oid = this._marshal.CreateVariable(extensions[i].oid); ext.stor.push(oid);
|
|
var x = this._marshal.PointerSize == 4 ? (16 * i) : (32 * i);
|
|
oid.pointerBuffer().copy(ext.Deref(x, this._marshal.PointerSize).toBuffer());
|
|
|
|
ext.Deref(x + this._marshal.PointerSize, 4).toBuffer().writeUInt32LE(1);
|
|
ext.Deref(x + (this._marshal.PointerSize == 4 ? 8 : 16), 4).toBuffer().writeUInt32LE(extensions[i]._size);
|
|
extensions[i].pointerBuffer().copy(ext.Deref(x + (this._marshal.PointerSize == 4 ? 12 : 24), this._marshal.PointerSize).toBuffer());
|
|
}
|
|
|
|
certinfo._ext = ext;
|
|
certinfo.Deref(this._marshal.PointerSize == 4 ? 104 : 192, 4).toBuffer().writeUInt32LE(extensions.length); // cExtension
|
|
ext.pointerBuffer().copy(certinfo.Deref(this._marshal.PointerSize == 4 ? 108 : 200, this._marshal.PointerSize).toBuffer()); // rgExtension
|
|
}
|
|
|
|
|
|
return (certinfo);
|
|
};
|
|
|
|
this.SignCertificate = function SignCertificate(signingCert, certinfo)
|
|
{
|
|
var sig = this._marshal.CreateVariable(this._marshal.PointerSize == 4 ? 12 : 24);
|
|
sig.oid = this._marshal.CreateVariable(CRYPT_ALGORITHMS.SHA1);
|
|
sig.oid.pointerBuffer().copy(sig.Deref(0, this._marshal.PointerSize).toBuffer());
|
|
var dwSize = this._marshal.CreateVariable(4);
|
|
|
|
if (this._Crypt32.CryptSignAndEncodeCertificate(signingCert.privateKey, signingCert.privateKey.keySpec, this.X509_ASN_ENCODING, X509_CERT_TO_BE_SIGNED, certinfo, sig, 0, 0, dwSize).Val != 0)
|
|
{
|
|
// success
|
|
var pbEncoded = this._marshal.CreateVariable(dwSize.toBuffer().readUInt32LE());
|
|
console.log('KeySpec: ' + signingCert.privateKey.keySpec);
|
|
console.log(this._Crypt32.CryptSignAndEncodeCertificate(signingCert.privateKey, signingCert.privateKey.keySpec, X509_ASN_ENCODING, X509_CERT_TO_BE_SIGNED, certinfo, sig, 0, pbEncoded, dwSize).Val);
|
|
console.log('dwSize: ' + dwSize.toBuffer().readUInt32LE());
|
|
pbEncoded._size = dwSize.toBuffer().readUInt32LE();
|
|
return (pbEncoded);
|
|
}
|
|
else {
|
|
throw ('Error: ' + this._Kernel32.GetLastError().Val);
|
|
}
|
|
};
|
|
this.SignCertRequest_old = function SignCertRequest_old(signingCert, publicKeyInfo)
|
|
{
|
|
//var certRequestInfo = this.MakeCertRequestInfo(publicKeyInfo.subject, publicKeyInfo);
|
|
var certRequestInfo = this._marshal.CreateVariable(this._marshal.PointerSize == 4 ? 44 : 88);
|
|
certRequestInfo.subject = certRequestInfo.Deref(this._marshal.PointerSize == 4 ? 4 : 8, this._marshal.PointerSize == 4 ? 8 : 16);
|
|
certRequestInfo.subjectPublicKeyInfo = certRequestInfo.Deref(this._marshal.PointerSize == 4 ? 12 : 24, this._marshal.PointerSize == 4 ? 24 : 48);
|
|
|
|
signingCert.Subject.toBuffer().copy(certRequestInfo.subject.toBuffer());
|
|
signingCert.SubjectPublicKeyInfo.toBuffer().copy(certRequestInfo.subjectPublicKeyInfo.toBuffer());
|
|
|
|
var sig = this._marshal.CreateVariable(this._marshal.PointerSize == 4 ? 12 : 24);
|
|
sig.oid = this._marshal.CreateVariable(CRYPT_ALGORITHMS.SHA1);
|
|
sig.oid.pointerBuffer().copy(sig.Deref(0,this._marshal.PointerSize).toBuffer());
|
|
var dwSize = this._marshal.CreateVariable(4);
|
|
|
|
if (this._Crypt32.CryptSignAndEncodeCertificate(signingCert.privateKey, signingCert.privateKey.keySpec, this.X509_ASN_ENCODING, X509_CERT_REQUEST_TO_BE_SIGNED, certRequestInfo, sig, 0, 0, dwSize).Val != 0)
|
|
{
|
|
// success
|
|
var pbEncoded = this._marshal.CreateVariable(dwSize.toBuffer().readUInt32LE());
|
|
console.log('KeySpec: ' + signingCert.privateKey.keySpec);
|
|
console.log(this._Crypt32.CryptSignAndEncodeCertificate(signingCert.privateKey, signingCert.privateKey.keySpec, X509_ASN_ENCODING, X509_CERT_REQUEST_TO_BE_SIGNED, certRequestInfo, sig, 0, pbEncoded, dwSize).Val);
|
|
console.log('dwSize: ' + dwSize.toBuffer().readUInt32LE());
|
|
pbEncoded._size = dwSize.toBuffer().readUInt32LE();
|
|
return (pbEncoded);
|
|
}
|
|
else
|
|
{
|
|
throw ('Error: ' + this._Kernel32.GetLastError().Val);
|
|
}
|
|
};
|
|
this.dateToFileTime = function dateToFileTime(dt)
|
|
{
|
|
var systemtime = this._marshal.CreateVariable(16);
|
|
var filetime = this._marshal.CreateVariable(8);
|
|
|
|
systemtime.Deref(0,2).toBuffer().writeUInt16LE(dt.getUTCFullYear());
|
|
systemtime.Deref(2, 2).toBuffer().writeUInt16LE(dt.getUTCMonth() + 1);
|
|
systemtime.Deref(6, 2).toBuffer().writeUInt16LE(dt.getUTCDate());
|
|
systemtime.Deref(8, 2).toBuffer().writeUInt16LE(dt.getUTCHours());
|
|
systemtime.Deref(10, 2).toBuffer().writeUInt16LE(dt.getUTCMinutes());
|
|
systemtime.Deref(12, 2).toBuffer().writeUInt16LE(dt.getUTCSeconds());
|
|
systemtime.Deref(14, 2).toBuffer().writeUInt16LE(dt.getUTCMilliseconds());
|
|
|
|
if(this._Kernel32.SystemTimeToFileTime(systemtime, filetime).Val == 0)
|
|
{
|
|
throw ('Error converting time: ' + this._Kernel32.GetLastError().Val);
|
|
}
|
|
return (filetime);
|
|
};
|
|
this.fileTimeToDate = function fileTimeToDate(ft)
|
|
{
|
|
var systemtime = this._marshal.CreateVariable(16);
|
|
if(this._Kernel32.FileTimeToSystemTime(ft, systemtime).Val == 0)
|
|
{
|
|
throw ('Error convertin filetime: ' + this._Kernel32.GetLastError().Val);
|
|
}
|
|
|
|
var ret = Date.now();
|
|
var buffer = systemtime.toBuffer();
|
|
|
|
ret.setUTCFullYear(buffer.readUInt16LE(0));
|
|
ret.setUTCMonth(buffer.readUInt16LE(2));
|
|
ret.setUTCDate(buffer.readUInt16LE(6));
|
|
ret.setUTCHours(buffer.readUInt16LE(8));
|
|
ret.setUTCMinutes(buffer.readUInt16LE(10));
|
|
ret.setUTCSeconds(buffer.readUInt16LE(12));
|
|
ret.setUTCMilliseconds(buffer.readUInt16LE(14));
|
|
|
|
return (ret);
|
|
};
|
|
}
|
|
function getInfo(options)
|
|
{
|
|
var certInfo = this.Deref(this._marshal.PointerSize == 4 ? 12 : 24, this._marshal.PointerSize).Deref(this._marshal.PointerSize == 4 ? 112 : 208);
|
|
var signatureAlgorithm = certInfo.Deref(this._marshal.PointerSize == 4 ? 12 : 24, this._marshal.PointerSize);
|
|
var publicKeyInfo = certInfo.Deref(this._marshal.PointerSize == 4 ? 56 : 96, this._marshal.PointerSize == 4 ? 24 : 48);
|
|
var keyAlgorithm = publicKeyInfo.Deref(0, this._marshal.PointerSize == 4 ? 12 : 24);
|
|
var publicKeyLen = publicKeyInfo.Deref(this._marshal.PointerSize == 4 ? 12 : 24, 4).toBuffer().readUInt32LE();
|
|
var publicKey = publicKeyInfo.Deref(this._marshal.PointerSize == 4 ? 16 : 32, this._marshal.PointerSize).Deref(publicKeyLen).toBuffer().toString('base64');
|
|
|
|
var thumbprintHash = 'SHA1Stream';
|
|
if (options)
|
|
{
|
|
switch(options.thumbprint)
|
|
{
|
|
case 'MD5':
|
|
thumbprintHash = 'MD5Stream';
|
|
break;
|
|
case 'SHA1':
|
|
thumbprintHash = 'SHA1Stream';
|
|
break;
|
|
case 'SHA256':
|
|
thumbprintHash = 'SHA256Stream';
|
|
break;
|
|
case 'SHA384':
|
|
thumbprintHash = 'SHA384Stream';
|
|
break;
|
|
case 'SHA512':
|
|
thumbprintHash = 'SHA512Stream';
|
|
break;
|
|
}
|
|
}
|
|
|
|
var retVal = {};
|
|
retVal.version = certInfo.toBuffer().readUInt32LE();
|
|
retVal.signatureAlgorithm = CRYPT_ALGORITHMS_EX[signatureAlgorithm.Deref().String];
|
|
retVal.keyAlgorithm = CRYPT_KEY_ALGORITHMS[keyAlgorithm.Deref().String];
|
|
retVal.publicKey = publicKey;
|
|
retVal.thumbprint = require(thumbprintHash).create().syncHash(this._raw.toBuffer()).toString('hex');
|
|
retVal.thumbprintAlgorithm = options ? options.thumbprint : 'SHA1';
|
|
return (retVal);
|
|
}
|
|
|
|
|
|
|
|
module.exports = new WinCrypto();
|
|
|
|
//var cng = new WinCrypto();
|
|
//var cert = cng.makeCert({ CN: 'Bryan Test', T: 'My Title', _algorithm: 'SHA256', _years: 1 });
|
|
//var msg = cert.signMessage(Buffer.from('this is testing'), { hashAlgorithm: 'SHA256', encodingType: PKCS_7_ASN_ENCODING });
|
|
//console.log(msg.toString('hex'));
|
|
|
|
//var pkcs7 = require('pkcs7');
|
|
//var result = pkcs7.getSignedDataBlock(msg);
|
|
//console.log(result.data, result.signingCertificate.publicKeyHash, result.signingCertificate.fingerprint);
|
|
|
|
//var decoded = cng.verifyMessage(msg, { encodingType: PKCS_7_ASN_ENCODING });
|
|
//console.log(decoded.toString());
|