2 * Copyright (c) 2014-2015 Sylvain Peyrefitte
4 * This file is part of node-rdpjs.
6 * node-rdpjs is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20var type = require('../core').type;
21var log = require('../core').log;
22var x509 = require('../security').x509;
23var rsa = require('../security').rsa;
24var asn1 = require('../asn1');
27 * @see http://msdn.microsoft.com/en-us/library/cc240521.aspx
29var CertificateType = {
30 CERT_CHAIN_VERSION_1 : 0x00000001,
31 CERT_CHAIN_VERSION_2 : 0x00000002
35 * @see http://msdn.microsoft.com/en-us/library/cc240520.aspx
38function rsaPublicKey(opt) {
40 magic : new type.UInt32Le(0x31415352, { constant : true }),
41 keylen : new type.UInt32Le(function() {
42 return self.modulus.size() + self.paddinf.size();
44 bitlen : new type.UInt32Le(function() {
45 return (self.keylen.value - 8) * 8;
47 datalen : new type.UInt32Le(function() {
48 return (self.bitlen.value / 8) - 1;
50 pubExp : new type.UInt32Le(),
51 modulus : new type.BinaryString(null, { readLength : new type.CallableValue(function() {
52 return self.keylen.value - 8;
54 padding : new type.BinaryString(Buffer.from(Array(8 + 1).join('\x00')), { readLength : new type.CallableValue(8) })
57 return new type.Component(self, opt);
61 * http://msdn.microsoft.com/en-us/library/cc240519.aspx
62 * @returns {type.Component}
64function proprietaryCertificate() {
66 __TYPE__ : CertificateType.CERT_CHAIN_VERSION_1,
67 dwSigAlgId : new type.UInt32Le(0x00000001, { constant : true }),
68 dwKeyAlgId : new type.UInt32Le(0x00000001, { constant : true }),
69 wPublicKeyBlobType : new type.UInt16Le(0x0006, { constant : true }),
70 wPublicKeyBlobLen : new type.UInt16Le(function() {
71 return self.PublicKeyBlob.size();
73 PublicKeyBlob : rsaPublicKey({ readLength : new type.CallableValue(function() {
74 return self.wPublicKeyBlobLen.value;
76 wSignatureBlobType : new type.UInt16Le(0x0008, { constant : true }),
77 wSignatureBlobLen : new type.UInt16Le(function() {
78 return self.SignatureBlob.size() + self.padding.size();
80 SignatureBlob : new type.BinaryString(null, { readLength : new type.CallableValue(function() {
81 return self.wSignatureBlobLen.value - self.padding.size;
83 padding : new type.BinaryString(Array(8 + 1).join('\x00'), { readLength : new type.CallableValue(8) }),
85 * @return {object} rsa.publicKey
87 getPublicKey : function() {
88 return rsa.publicKey(self.PublicKeyBlob.obj.modulus.value, self.PublicKeyBlob.obj.pubExp.value);
92 return new type.Component(self);
96 * For x509 certificate
97 * @see http://msdn.microsoft.com/en-us/library/cc241911.aspx
98 * @returns {type.Component}
102 cbCert : new type.UInt32Le(function() {
103 return self.abCert.size();
105 abCert : new type.BinaryString(null, { readLength : new type.CallableValue(function() {
106 return self.cbCert.value;
110 return new type.Component(self);
114 * x509 certificate chain
115 * @see http://msdn.microsoft.com/en-us/library/cc241910.aspx
116 * @returns {type.Component}
118function x509CertificateChain() {
120 __TYPE__ : CertificateType.CERT_CHAIN_VERSION_2,
121 NumCertBlobs : new type.UInt32Le(),
122 CertBlobArray : new type.Factory(function(s) {
123 self.CertBlobArray = new type.Component([]);
124 for(var i = 0; i < self.NumCertBlobs.value; i++) {
125 self.CertBlobArray.obj.push(certBlob().read(s));
128 padding : new type.BinaryString(null, { readLength : new type.CallableValue(function() {
129 return 8 + 4 * self.NumCertBlobs.value;
132 * @return {object} {n : modulus{bignum}, e : publicexponent{integer}
134 getPublicKey : function(){
135 var cert = x509.X509Certificate().decode(new type.Stream(self.CertBlobArray.obj[self.CertBlobArray.obj.length - 1].obj.abCert.value), asn1.ber);
136 var publikeyStream = new type.Stream(cert.value.tbsCertificate.value.subjectPublicKeyInfo.value.subjectPublicKey.toBuffer());
137 var asn1PublicKey = x509.RSAPublicKey().decode(publikeyStream, asn1.ber);
138 return rsa.publicKey(asn1PublicKey.value.modulus.value, asn1PublicKey.value.publicExponent.value);
142 return new type.Component(self);
145function certificate() {
147 dwVersion : new type.UInt32Le(function() {
148 return self.certData.__TYPE__;
150 certData : new type.Factory(function(s) {
151 switch(self.dwVersion.value & 0x7fffffff) {
152 case CertificateType.CERT_CHAIN_VERSION_1:
153 log.debug('read proprietary certificate');
154 self.certData = proprietaryCertificate().read(s);
156 case CertificateType.CERT_CHAIN_VERSION_2:
157 log.debug('read x.509 certificate chain');
158 self.certData = x509CertificateChain().read(s);
161 log.error('unknown cert type ' + self.dwVersion.value & 0x7fffffff);
166 return new type.Component(self);
173 CertificateType : CertificateType,
174 certificate : certificate