cert.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. * Copyright (c) 2014-2015 Sylvain Peyrefitte
  3. *
  4. * This file is part of node-rdpjs.
  5. *
  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.
  10. *
  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.
  15. *
  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/>.
  18. */
  19. var type = require('../core').type;
  20. var log = require('../core').log;
  21. var x509 = require('../security').x509;
  22. var rsa = require('../security').rsa;
  23. var asn1 = require('../asn1');
  24. /**
  25. *  @see http://msdn.microsoft.com/en-us/library/cc240521.aspx
  26. */
  27. var CertificateType = {
  28. CERT_CHAIN_VERSION_1 : 0x00000001,
  29. CERT_CHAIN_VERSION_2 : 0x00000002
  30. };
  31. /**
  32. * @see http://msdn.microsoft.com/en-us/library/cc240520.aspx
  33. * @returns
  34. */
  35. function rsaPublicKey(opt) {
  36. var self = {
  37. magic : new type.UInt32Le(0x31415352, { constant : true }),
  38. keylen : new type.UInt32Le(function() {
  39. return self.modulus.size() + self.paddinf.size();
  40. }),
  41. bitlen : new type.UInt32Le(function() {
  42. return (self.keylen.value - 8) * 8;
  43. }),
  44. datalen : new type.UInt32Le(function() {
  45. return (self.bitlen.value / 8) - 1;
  46. }),
  47. pubExp : new type.UInt32Le(),
  48. modulus : new type.BinaryString(null, { readLength : new type.CallableValue(function() {
  49. return self.keylen.value - 8;
  50. }) }),
  51. padding : new type.BinaryString(Buffer.from(Array(8 + 1).join('\x00')), { readLength : new type.CallableValue(8) })
  52. };
  53. return new type.Component(self, opt);
  54. }
  55. /**
  56. * http://msdn.microsoft.com/en-us/library/cc240519.aspx
  57. * @returns {type.Component}
  58. */
  59. function proprietaryCertificate() {
  60. var self = {
  61. __TYPE__ : CertificateType.CERT_CHAIN_VERSION_1,
  62. dwSigAlgId : new type.UInt32Le(0x00000001, { constant : true }),
  63. dwKeyAlgId : new type.UInt32Le(0x00000001, { constant : true }),
  64. wPublicKeyBlobType : new type.UInt16Le(0x0006, { constant : true }),
  65. wPublicKeyBlobLen : new type.UInt16Le(function() {
  66. return self.PublicKeyBlob.size();
  67. }),
  68. PublicKeyBlob : rsaPublicKey({ readLength : new type.CallableValue(function() {
  69. return self.wPublicKeyBlobLen.value;
  70. }) }),
  71. wSignatureBlobType : new type.UInt16Le(0x0008, { constant : true }),
  72. wSignatureBlobLen : new type.UInt16Le(function() {
  73. return self.SignatureBlob.size() + self.padding.size();
  74. }),
  75. SignatureBlob : new type.BinaryString(null, { readLength : new type.CallableValue(function() {
  76. return self.wSignatureBlobLen.value - self.padding.size;
  77. }) }),
  78. padding : new type.BinaryString(Array(8 + 1).join('\x00'), { readLength : new type.CallableValue(8) }),
  79. /**
  80. * @return {object} rsa.publicKey
  81. */
  82. getPublicKey : function() {
  83. return rsa.publicKey(self.PublicKeyBlob.obj.modulus.value, self.PublicKeyBlob.obj.pubExp.value);
  84. }
  85. };
  86. return new type.Component(self);
  87. }
  88. /**
  89. * For x509 certificate
  90. * @see http://msdn.microsoft.com/en-us/library/cc241911.aspx
  91. * @returns {type.Component}
  92. */
  93. function certBlob() {
  94. var self = {
  95. cbCert : new type.UInt32Le(function() {
  96. return self.abCert.size();
  97. }),
  98. abCert : new type.BinaryString(null, { readLength : new type.CallableValue(function() {
  99. return self.cbCert.value;
  100. }) })
  101. };
  102. return new type.Component(self);
  103. }
  104. /**
  105. * x509 certificate chain
  106. * @see http://msdn.microsoft.com/en-us/library/cc241910.aspx
  107. * @returns {type.Component}
  108. */
  109. function x509CertificateChain() {
  110. var self = {
  111. __TYPE__ : CertificateType.CERT_CHAIN_VERSION_2,
  112. NumCertBlobs : new type.UInt32Le(),
  113. CertBlobArray : new type.Factory(function(s) {
  114. self.CertBlobArray = new type.Component([]);
  115. for(var i = 0; i < self.NumCertBlobs.value; i++) {
  116. self.CertBlobArray.obj.push(certBlob().read(s));
  117. }
  118. }),
  119. padding : new type.BinaryString(null, { readLength : new type.CallableValue(function() {
  120. return 8 + 4 * self.NumCertBlobs.value;
  121. }) }),
  122. /**
  123. * @return {object} {n : modulus{bignum}, e : publicexponent{integer}
  124. */
  125. getPublicKey : function(){
  126. var cert = x509.X509Certificate().decode(new type.Stream(self.CertBlobArray.obj[self.CertBlobArray.obj.length - 1].obj.abCert.value), asn1.ber);
  127. var publikeyStream = new type.Stream(cert.value.tbsCertificate.value.subjectPublicKeyInfo.value.subjectPublicKey.toBuffer());
  128. var asn1PublicKey = x509.RSAPublicKey().decode(publikeyStream, asn1.ber);
  129. return rsa.publicKey(asn1PublicKey.value.modulus.value, asn1PublicKey.value.publicExponent.value);
  130. }
  131. };
  132. return new type.Component(self);
  133. }
  134. function certificate() {
  135. var self = {
  136. dwVersion : new type.UInt32Le(function() {
  137. return self.certData.__TYPE__;
  138. }),
  139. certData : new type.Factory(function(s) {
  140. switch(self.dwVersion.value & 0x7fffffff) {
  141. case CertificateType.CERT_CHAIN_VERSION_1:
  142. log.debug('read proprietary certificate');
  143. self.certData = proprietaryCertificate().read(s);
  144. break;
  145. case CertificateType.CERT_CHAIN_VERSION_2:
  146. log.debug('read x.509 certificate chain');
  147. self.certData = x509CertificateChain().read(s);
  148. break;
  149. default:
  150. log.error('unknown cert type ' + self.dwVersion.value & 0x7fffffff);
  151. }
  152. })
  153. };
  154. return new type.Component(self);
  155. }
  156. /**
  157. * Module exports
  158. */
  159. module.exports = {
  160. CertificateType : CertificateType,
  161. certificate : certificate
  162. };