doc: improvements to console.markdown copy
[platform/upstream/nodejs.git] / lib / _tls_common.js
1 'use strict';
2
3 const constants = require('constants');
4 const tls = require('tls');
5
6 // Lazily loaded
7 var crypto = null;
8
9 const binding = process.binding('crypto');
10 const NativeSecureContext = binding.SecureContext;
11
12 function SecureContext(secureProtocol, flags, context) {
13   if (!(this instanceof SecureContext)) {
14     return new SecureContext(secureProtocol, flags, context);
15   }
16
17   if (context) {
18     this.context = context;
19   } else {
20     this.context = new NativeSecureContext();
21
22     if (secureProtocol) {
23       this.context.init(secureProtocol);
24     } else {
25       this.context.init();
26     }
27   }
28
29   if (flags) this.context.setOptions(flags);
30 }
31
32 exports.SecureContext = SecureContext;
33
34
35 exports.createSecureContext = function createSecureContext(options, context) {
36   if (!options) options = {};
37
38   var secureOptions = options.secureOptions;
39   if (options.honorCipherOrder)
40     secureOptions |= constants.SSL_OP_CIPHER_SERVER_PREFERENCE;
41
42   var c = new SecureContext(options.secureProtocol, secureOptions, context);
43
44   if (context) return c;
45
46   // NOTE: It's important to add CA before the cert to be able to load
47   // cert's issuer in C++ code.
48   if (options.ca) {
49     if (Array.isArray(options.ca)) {
50       for (var i = 0, len = options.ca.length; i < len; i++) {
51         c.context.addCACert(options.ca[i]);
52       }
53     } else {
54       c.context.addCACert(options.ca);
55     }
56   } else {
57     c.context.addRootCerts();
58   }
59
60   if (options.cert) {
61     if (Array.isArray(options.cert)) {
62       for (var i = 0; i < options.cert.length; i++)
63         c.context.setCert(options.cert[i]);
64     } else {
65       c.context.setCert(options.cert);
66     }
67   }
68
69   // NOTE: It is important to set the key after the cert.
70   // `ssl_set_pkey` returns `0` when the key does not much the cert, but
71   // `ssl_set_cert` returns `1` and nullifies the key in the SSL structure
72   // which leads to the crash later on.
73   if (options.key) {
74     if (Array.isArray(options.key)) {
75       for (var i = 0; i < options.key.length; i++) {
76         var key = options.key[i];
77
78         if (key.passphrase)
79           c.context.setKey(key.pem, key.passphrase);
80         else
81           c.context.setKey(key);
82       }
83     } else {
84       if (options.passphrase) {
85         c.context.setKey(options.key, options.passphrase);
86       } else {
87         c.context.setKey(options.key);
88       }
89     }
90   }
91
92   if (options.ciphers)
93     c.context.setCiphers(options.ciphers);
94   else
95     c.context.setCiphers(tls.DEFAULT_CIPHERS);
96
97   if (options.ecdhCurve === undefined)
98     c.context.setECDHCurve(tls.DEFAULT_ECDH_CURVE);
99   else if (options.ecdhCurve)
100     c.context.setECDHCurve(options.ecdhCurve);
101
102   if (options.dhparam) c.context.setDHParam(options.dhparam);
103
104   if (options.crl) {
105     if (Array.isArray(options.crl)) {
106       for (var i = 0, len = options.crl.length; i < len; i++) {
107         c.context.addCRL(options.crl[i]);
108       }
109     } else {
110       c.context.addCRL(options.crl);
111     }
112   }
113
114   if (options.sessionIdContext) {
115     c.context.setSessionIdContext(options.sessionIdContext);
116   }
117
118   if (options.pfx) {
119     var pfx = options.pfx;
120     var passphrase = options.passphrase;
121
122     if (!crypto)
123       crypto = require('crypto');
124
125     pfx = crypto._toBuf(pfx);
126     if (passphrase)
127       passphrase = crypto._toBuf(passphrase);
128
129     if (passphrase) {
130       c.context.loadPKCS12(pfx, passphrase);
131     } else {
132       c.context.loadPKCS12(pfx);
133     }
134   }
135
136   // Do not keep read/write buffers in free list
137   if (options.singleUse) {
138     c.singleUse = true;
139     c.context.setFreeListLength(0);
140   }
141
142   return c;
143 };
144
145 exports.translatePeerCertificate = function translatePeerCertificate(c) {
146   if (!c)
147     return null;
148
149   if (c.issuer) c.issuer = tls.parseCertString(c.issuer);
150   if (c.issuerCertificate && c.issuerCertificate !== c) {
151     c.issuerCertificate = translatePeerCertificate(c.issuerCertificate);
152   }
153   if (c.subject) c.subject = tls.parseCertString(c.subject);
154   if (c.infoAccess) {
155     var info = c.infoAccess;
156     c.infoAccess = {};
157
158     // XXX: More key validation?
159     info.replace(/([^\n:]*):([^\n]*)(?:\n|$)/g, function(all, key, val) {
160       if (key === '__proto__')
161         return;
162
163       if (c.infoAccess.hasOwnProperty(key))
164         c.infoAccess[key].push(val);
165       else
166         c.infoAccess[key] = [val];
167     });
168   }
169   return c;
170 };