lemon-tls 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "lemon-tls",
3
- "version": "0.3.0",
4
- "description": "Zero-dependency TLS 1.3/1.2 implementation for Node.js - full control over cryptographic keys, record layer, and handshake. Drop-in replacement for node:tls with advanced options impossible in OpenSSL.",
3
+ "version": "0.4.0",
4
+ "description": "TLS 1.3/1.2 implementation for Node.js - full control over cryptographic keys, record layer, and handshake. Drop-in replacement for node:tls with advanced options impossible in OpenSSL.",
5
5
  "main": "index.js",
6
6
  "type": "module",
7
7
  "types": "index.d.ts",
@@ -44,6 +44,7 @@ function DTLSSocket(udpSocket, options) {
44
44
  cert: options.cert,
45
45
  key: options.key,
46
46
  rejectUnauthorized: options.rejectUnauthorized,
47
+ requestCert: options.requestCert,
47
48
  ca: options.ca,
48
49
  alpnProtocols: options.alpnProtocols,
49
50
  minVersion: options.minVersion,
@@ -159,6 +160,7 @@ function createDTLSServer(options, connectionListener) {
159
160
  remotePort: rinfo.port,
160
161
  cert: options.cert,
161
162
  key: options.key,
163
+ requestCert: options.requestCert,
162
164
  SNICallback: options.SNICallback,
163
165
  alpnProtocols: options.alpnProtocols,
164
166
  minVersion: options.minVersion,
@@ -239,6 +241,7 @@ function connectDTLS(options, callback) {
239
241
  remotePort: port,
240
242
  servername: options.servername || host,
241
243
  rejectUnauthorized: options.rejectUnauthorized,
244
+ requestCert: options.requestCert,
242
245
  ca: options.ca,
243
246
  alpnProtocols: options.alpnProtocols,
244
247
  minVersion: options.minVersion,
@@ -29,7 +29,7 @@ function normalize_hello(hello) {
29
29
  } else if (name === 'KEY_SHARE') {
30
30
  if (!('key_groups' in out)) out.key_groups = [];
31
31
  if (!('supported_groups' in out)) out.supported_groups = [];
32
- for (let i2 in value) {
32
+ for (let i2 = 0; i2 < value.length; i2++) {
33
33
  if (out.supported_groups.indexOf(value[i2].group) < 0) {
34
34
  out.supported_groups.push(value[i2].group);
35
35
  }
@@ -533,7 +533,7 @@ function TLSSession(options){
533
533
  }
534
534
 
535
535
  // Custom extensions (e.g. QUIC transport params 0x39)
536
- for (let ci in context.local_extensions) {
536
+ for (let ci = 0; ci < context.local_extensions.length; ci++) {
537
537
  extensions.push(context.local_extensions[ci]);
538
538
  }
539
539
 
@@ -999,7 +999,7 @@ function TLSSession(options){
999
999
 
1000
1000
 
1001
1001
  if('add_local_key_groups' in options){
1002
- for(let i in options['add_local_key_groups']){
1002
+ for(let i = 0; i < options['add_local_key_groups'].length; i++){
1003
1003
 
1004
1004
  let group=options['add_local_key_groups'][i].group;
1005
1005
  if(group in context.local_key_groups==false){
@@ -1029,7 +1029,7 @@ function TLSSession(options){
1029
1029
 
1030
1030
 
1031
1031
  if('add_remote_key_groups' in options){
1032
- for(let i in options['add_remote_key_groups']){
1032
+ for(let i = 0; i < options['add_remote_key_groups'].length; i++){
1033
1033
 
1034
1034
  let group=options['add_remote_key_groups'][i].group;
1035
1035
  if(group in context.remote_key_groups==false){
@@ -1779,7 +1779,7 @@ function TLSSession(options){
1779
1779
  }
1780
1780
 
1781
1781
 
1782
- for(let i in context.local_extensions){
1782
+ for(let i = 0; i < context.local_extensions.length; i++){
1783
1783
  extensions.push(context.local_extensions[i]);
1784
1784
  }
1785
1785
 
@@ -2105,6 +2105,41 @@ function TLSSession(options){
2105
2105
  }
2106
2106
  }
2107
2107
 
2108
+ // TLS 1.2 / DTLS 1.2 server: send CertificateRequest if mutual auth was
2109
+ // requested via { requestCert: true }. Per RFC 5246 §7.4.4 this message
2110
+ // goes between ServerKeyExchange and ServerHelloDone. The TLS 1.3 path
2111
+ // (line ~1805) sends CertificateRequest between EncryptedExtensions and
2112
+ // Certificate and is handled separately — version branching matters
2113
+ // because the wire formats differ (RFC 5246 §7.4.4 vs RFC 8446 §4.3.2).
2114
+ //
2115
+ // Without this block, a 1.2 server that sets requestCert never actually
2116
+ // requests the client's certificate, the client never sends one (TLS
2117
+ // clients only send a cert in response to CertificateRequest), and any
2118
+ // application-layer fingerprint check on the server fails with "peer
2119
+ // presented no certificate" — most notably breaking WebRTC, which
2120
+ // mandates mutual authentication (RFC 8827 §6.5) and pins to DTLS 1.2.
2121
+ if (context.isServer == true && context.requestCert == true &&
2122
+ !context.certificateRequestSent &&
2123
+ context.key_exchange_sent == true && !context.hello_done_sent &&
2124
+ (context.selected_version === wire.TLS_VERSION.TLS1_2 ||
2125
+ context.selected_version === wire.DTLS_VERSION.DTLS1_2)) {
2126
+
2127
+ let cr_body = wire.build_certificate_request({
2128
+ version: wire.TLS_VERSION.TLS1_2,
2129
+ // rsa_sign(1), ecdsa_sign(64) — accept both. WebRTC uses ECDSA,
2130
+ // most other 1.2 deployments use RSA. The client picks whichever
2131
+ // matches its certificate.
2132
+ certificate_types: [1, 64],
2133
+ signature_algorithms: context.local_supported_signature_algorithms || [],
2134
+ certificate_authorities: [], // empty: accept any CA
2135
+ });
2136
+ let cr_data = wire.build_message(wire.TLS_MESSAGE_TYPE.CERTIFICATE_REQUEST, cr_body);
2137
+ pushTranscript(cr_data);
2138
+ context.certificateRequestSent = true;
2139
+ ev.emit('message', 0, context.message_sent_seq, 'certificate_request', cr_data);
2140
+ context.message_sent_seq++;
2141
+ }
2142
+
2108
2143
  //server hello done - 1.2 only...
2109
2144
  if(context.isServer==true && (context.selected_version === wire.TLS_VERSION.TLS1_2 || context.selected_version === wire.DTLS_VERSION.DTLS1_2)){
2110
2145
  if(context.hello_done_sent==false && context.key_exchange_sent==true){
@@ -2730,7 +2765,7 @@ function TLSSession(options){
2730
2765
  }
2731
2766
 
2732
2767
  // Add custom extensions (e.g. QUIC transport params 0x39)
2733
- for (let i in context.local_extensions) {
2768
+ for (let i = 0; i < context.local_extensions.length; i++) {
2734
2769
  extensions.push(context.local_extensions[i]);
2735
2770
  }
2736
2771