@@ -243,14 +243,30 @@ added: v0.3.4
243
243
* ` requestListener ` {Function} A listener to be added to the ` 'request' ` event.
244
244
* Returns: {https.Server}
245
245
246
- ``` js
246
+ ``` mjs
247
+ // curl -k https://localhost:8000/
248
+ import { createServer } from ' node:https' ;
249
+ import { readFileSync } from ' node:fs' ;
250
+
251
+ const options = {
252
+ key: readFileSync (' private-key.pem' ),
253
+ cert: readFileSync (' certificate.pem' ),
254
+ };
255
+
256
+ createServer (options, (req , res ) => {
257
+ res .writeHead (200 );
258
+ res .end (' hello world\n ' );
259
+ }).listen (8000 );
260
+ ```
261
+
262
+ ``` cjs
247
263
// curl -k https://localhost:8000/
248
264
const https = require (' node:https' );
249
265
const fs = require (' node:fs' );
250
266
251
267
const options = {
252
- key: fs .readFileSync (' test/fixtures/keys/agent2 -key.pem' ),
253
- cert: fs .readFileSync (' test/fixtures/keys/agent2-cert .pem' ),
268
+ key: fs .readFileSync (' private -key.pem' ),
269
+ cert: fs .readFileSync (' certificate .pem' ),
254
270
};
255
271
256
272
https .createServer (options, (req , res ) => {
@@ -261,12 +277,27 @@ https.createServer(options, (req, res) => {
261
277
262
278
Or
263
279
264
- ``` js
280
+ ``` mjs
281
+ import { createServer } from ' node:https' ;
282
+ import { readFileSync } from ' node:fs' ;
283
+
284
+ const options = {
285
+ pfx: readFileSync (' test_cert.pfx' ),
286
+ passphrase: ' sample' ,
287
+ };
288
+
289
+ createServer (options, (req , res ) => {
290
+ res .writeHead (200 );
291
+ res .end (' hello world\n ' );
292
+ }).listen (8000 );
293
+ ```
294
+
295
+ ``` cjs
265
296
const https = require (' node:https' );
266
297
const fs = require (' node:fs' );
267
298
268
299
const options = {
269
- pfx: fs .readFileSync (' test/fixtures/ test_cert.pfx' ),
300
+ pfx: fs .readFileSync (' test_cert.pfx' ),
270
301
passphrase: ' sample' ,
271
302
};
272
303
@@ -276,6 +307,20 @@ https.createServer(options, (req, res) => {
276
307
}).listen (8000 );
277
308
```
278
309
310
+ To generate the certificate and key for this example, run:
311
+
312
+ ``` bash
313
+ openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj ' /CN=localhost' \
314
+ -keyout private-key.pem -out certificate.pem
315
+ ```
316
+
317
+ Then, to generate the ` pfx ` certificate for this example, run:
318
+
319
+ ``` bash
320
+ openssl pkcs12 -certpbe AES-256-CBC -export -out test_cert.pfx \
321
+ -inkey private-key.pem -in certificate.pem -passout pass:sample
322
+ ```
323
+
279
324
## ` https.get(options[, callback]) `
280
325
281
326
## ` https.get(url[, options][, callback]) `
@@ -303,7 +348,24 @@ Like [`http.get()`][] but for HTTPS.
303
348
string, it is automatically parsed with [ ` new URL() ` ] [ ] . If it is a [ ` URL ` ] [ ]
304
349
object, it will be automatically converted to an ordinary ` options ` object.
305
350
306
- ``` js
351
+ ``` mjs
352
+ import { get } from ' node:https' ;
353
+ import process from ' node:process' ;
354
+
355
+ get (' https://encrypted.google.com/' , (res ) => {
356
+ console .log (' statusCode:' , res .statusCode );
357
+ console .log (' headers:' , res .headers );
358
+
359
+ res .on (' data' , (d ) => {
360
+ process .stdout .write (d);
361
+ });
362
+
363
+ }).on (' error' , (e ) => {
364
+ console .error (e);
365
+ });
366
+ ```
367
+
368
+ ``` cjs
307
369
const https = require (' node:https' );
308
370
309
371
https .get (' https://encrypted.google.com/' , (res ) => {
@@ -396,7 +458,33 @@ object, it will be automatically converted to an ordinary `options` object.
396
458
class. The ` ClientRequest ` instance is a writable stream. If one needs to
397
459
upload a file with a POST request, then write to the ` ClientRequest ` object.
398
460
399
- ``` js
461
+ ``` mjs
462
+ import { request } from ' node:https' ;
463
+ import process from ' node:process' ;
464
+
465
+ const options = {
466
+ hostname: ' encrypted.google.com' ,
467
+ port: 443 ,
468
+ path: ' /' ,
469
+ method: ' GET' ,
470
+ };
471
+
472
+ const req = request (options, (res ) => {
473
+ console .log (' statusCode:' , res .statusCode );
474
+ console .log (' headers:' , res .headers );
475
+
476
+ res .on (' data' , (d ) => {
477
+ process .stdout .write (d);
478
+ });
479
+ });
480
+
481
+ req .on (' error' , (e ) => {
482
+ console .error (e);
483
+ });
484
+ req .end ();
485
+ ```
486
+
487
+ ``` cjs
400
488
const https = require (' node:https' );
401
489
402
490
const options = {
@@ -429,8 +517,8 @@ const options = {
429
517
port: 443 ,
430
518
path: ' /' ,
431
519
method: ' GET' ,
432
- key: fs .readFileSync (' test/fixtures/keys/agent2 -key.pem' ),
433
- cert: fs .readFileSync (' test/fixtures/keys/agent2-cert .pem' ),
520
+ key: fs .readFileSync (' private -key.pem' ),
521
+ cert: fs .readFileSync (' certificate .pem' ),
434
522
};
435
523
options .agent = new https.Agent (options);
436
524
@@ -447,8 +535,8 @@ const options = {
447
535
port: 443 ,
448
536
path: ' /' ,
449
537
method: ' GET' ,
450
- key: fs .readFileSync (' test/fixtures/keys/agent2 -key.pem' ),
451
- cert: fs .readFileSync (' test/fixtures/keys/agent2-cert .pem' ),
538
+ key: fs .readFileSync (' private -key.pem' ),
539
+ cert: fs .readFileSync (' certificate .pem' ),
452
540
agent: false ,
453
541
};
454
542
@@ -470,7 +558,80 @@ const req = https.request(options, (res) => {
470
558
Example pinning on certificate fingerprint, or the public key (similar to
471
559
` pin-sha256 ` ):
472
560
473
- ``` js
561
+ ``` mjs
562
+ import { checkServerIdentity } from ' node:tls' ;
563
+ import { Agent , request } from ' node:https' ;
564
+ import { createHash } from ' node:crypto' ;
565
+
566
+ function sha256 (s ) {
567
+ return createHash (' sha256' ).update (s).digest (' base64' );
568
+ }
569
+ const options = {
570
+ hostname: ' github.com' ,
571
+ port: 443 ,
572
+ path: ' /' ,
573
+ method: ' GET' ,
574
+ checkServerIdentity : function (host , cert ) {
575
+ // Make sure the certificate is issued to the host we are connected to
576
+ const err = checkServerIdentity (host, cert);
577
+ if (err) {
578
+ return err;
579
+ }
580
+
581
+ // Pin the public key, similar to HPKP pin-sha256 pinning
582
+ const pubkey256 = ' SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8=' ;
583
+ if (sha256 (cert .pubkey ) !== pubkey256) {
584
+ const msg = ' Certificate verification error: ' +
585
+ ` The public key of '${ cert .subject .CN } ' ` +
586
+ ' does not match our pinned fingerprint' ;
587
+ return new Error (msg);
588
+ }
589
+
590
+ // Pin the exact certificate, rather than the pub key
591
+ const cert256 = ' FD:6E:9B:0E:F3:98:BC:D9:04:C3:B2:EC:16:7A:7B:' +
592
+ ' 0F:DA:72:01:C9:03:C5:3A:6A:6A:E5:D0:41:43:63:EF:65' ;
593
+ if (cert .fingerprint256 !== cert256) {
594
+ const msg = ' Certificate verification error: ' +
595
+ ` The certificate of '${ cert .subject .CN } ' ` +
596
+ ' does not match our pinned fingerprint' ;
597
+ return new Error (msg);
598
+ }
599
+
600
+ // This loop is informational only.
601
+ // Print the certificate and public key fingerprints of all certs in the
602
+ // chain. Its common to pin the public key of the issuer on the public
603
+ // internet, while pinning the public key of the service in sensitive
604
+ // environments.
605
+ let lastprint256;
606
+ do {
607
+ console .log (' Subject Common Name:' , cert .subject .CN );
608
+ console .log (' Certificate SHA256 fingerprint:' , cert .fingerprint256 );
609
+
610
+ const hash = createHash (' sha256' );
611
+ console .log (' Public key ping-sha256:' , sha256 (cert .pubkey ));
612
+
613
+ lastprint256 = cert .fingerprint256 ;
614
+ cert = cert .issuerCertificate ;
615
+ } while (cert .fingerprint256 !== lastprint256);
616
+
617
+ },
618
+ };
619
+
620
+ options .agent = new Agent (options);
621
+ const req = request (options, (res ) => {
622
+ console .log (' All OK. Server matched our pinned cert or public key' );
623
+ console .log (' statusCode:' , res .statusCode );
624
+
625
+ res .on (' data' , (d ) => {});
626
+ });
627
+
628
+ req .on (' error' , (e ) => {
629
+ console .error (e .message );
630
+ });
631
+ req .end ();
632
+ ```
633
+
634
+ ``` cjs
474
635
const tls = require (' node:tls' );
475
636
const https = require (' node:https' );
476
637
const crypto = require (' node:crypto' );
@@ -491,7 +652,7 @@ const options = {
491
652
}
492
653
493
654
// Pin the public key, similar to HPKP pin-sha256 pinning
494
- const pubkey256 = ' pL1+qb9HTMRZJmuC/bB/ZI9d302BYrrqiVuRyW+DGrU =' ;
655
+ const pubkey256 = ' SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8 =' ;
495
656
if (sha256 (cert .pubkey ) !== pubkey256) {
496
657
const msg = ' Certificate verification error: ' +
497
658
` The public key of '${ cert .subject .CN } ' ` +
@@ -500,8 +661,8 @@ const options = {
500
661
}
501
662
502
663
// Pin the exact certificate, rather than the pub key
503
- const cert256 = ' 25:FE:39:32:D9:63:8C:8A:FC:A1:9A:29:87 :' +
504
- ' D8:3E:4C:1D:98:DB:71:E4:1A:48:03:98:EA:22:6A:BD:8B:93:16 ' ;
664
+ const cert256 = ' FD:6E:9B:0E:F3:98:BC:D9:04:C3:B2:EC:16:7A:7B :' +
665
+ ' 0F:DA:72:01:C9:03:C5:3A:6A:6A:E5:D0:41:43:63:EF:65 ' ;
505
666
if (cert .fingerprint256 !== cert256) {
506
667
const msg = ' Certificate verification error: ' +
507
668
` The certificate of '${ cert .subject .CN } ' ` +
@@ -532,8 +693,6 @@ options.agent = new https.Agent(options);
532
693
const req = https .request (options, (res ) => {
533
694
console .log (' All OK. Server matched our pinned cert or public key' );
534
695
console .log (' statusCode:' , res .statusCode );
535
- // Print the HPKP values
536
- console .log (' headers:' , res .headers [' public-key-pins' ]);
537
696
538
697
res .on (' data' , (d ) => {});
539
698
});
@@ -548,17 +707,19 @@ Outputs for example:
548
707
549
708
``` text
550
709
Subject Common Name: github.com
551
- Certificate SHA256 fingerprint: 25:FE:39:32:D9:63:8C:8A:FC:A1:9A:29:87:D8:3E:4C:1D:98:DB:71:E4:1A:48:03:98:EA:22:6A:BD:8B:93:16
552
- Public key ping-sha256: pL1+qb9HTMRZJmuC/bB/ZI9d302BYrrqiVuRyW+DGrU=
553
- Subject Common Name: DigiCert SHA2 Extended Validation Server CA
554
- Certificate SHA256 fingerprint: 40:3E:06:2A:26:53:05:91:13:28:5B:AF:80:A0:D4:AE:42:2C:84:8C:9F:78:FA:D0:1F:C9:4B:C5:B8:7F:EF:1A
555
- Public key ping-sha256: RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=
556
- Subject Common Name: DigiCert High Assurance EV Root CA
557
- Certificate SHA256 fingerprint: 74:31:E5:F4:C3:C1:CE:46:90:77:4F:0B:61:E0:54:40:88:3B:A9:A0:1E:D0:0B:A6:AB:D7:80:6E:D3:B1:18:CF
558
- Public key ping-sha256: WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=
710
+ Certificate SHA256 fingerprint: FD:6E:9B:0E:F3:98:BC:D9:04:C3:B2:EC:16:7A:7B:0F:DA:72:01:C9:03:C5:3A:6A:6A:E5:D0:41:43:63:EF:65
711
+ Public key ping-sha256: SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8=
712
+ Subject Common Name: Sectigo ECC Domain Validation Secure Server CA
713
+ Certificate SHA256 fingerprint: 61:E9:73:75:E9:F6:DA:98:2F:F5:C1:9E:2F:94:E6:6C:4E:35:B6:83:7C:E3:B9:14:D2:24:5C:7F:5F:65:82:5F
714
+ Public key ping-sha256: Eep0p/AsSa9lFUH6KT2UY+9s1Z8v7voAPkQ4fGknZ2g=
715
+ Subject Common Name: USERTrust ECC Certification Authority
716
+ Certificate SHA256 fingerprint: A6:CF:64:DB:B4:C8:D5:FD:19:CE:48:89:60:68:DB:03:B5:33:A8:D1:33:6C:62:56:A8:7D:00:CB:B3:DE:F3:EA
717
+ Public key ping-sha256: UJM2FOhG9aTNY0Pg4hgqjNzZ/lQBiMGRxPD5Y2/e0bw=
718
+ Subject Common Name: AAA Certificate Services
719
+ Certificate SHA256 fingerprint: D7:A7:A0:FB:5D:7E:27:31:D7:71:E9:48:4E:BC:DE:F7:1D:5F:0C:3E:0A:29:48:78:2B:C8:3E:E0:EA:69:9E:F4
720
+ Public key ping-sha256: vRU+17BDT2iGsXvOi76E7TQMcTLXAqj0+jGPdW7L1vM=
559
721
All OK. Server matched our pinned cert or public key
560
722
statusCode: 200
561
- headers: max-age=0; pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="; pin-sha256="RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho="; pin-sha256="k2v657xBsOVe1PQRwOsHsw3bsGT2VzIqz5K+59sNQws="; pin-sha256="K87oWBWM9UZfyddvDfoxL+8lpNyoUB2ptGtn0fv6G2Q="; pin-sha256="IQBnNBEiFuhj+8x6X8XLgh01V9Ic5/V3IRQLNFFc7v4="; pin-sha256="iie1VXtL7HzAMF+/PVPR9xzT80kQxdZeJ+zduCB3uj0="; pin-sha256="LvRiGEjRqfzurezaWuj8Wie2gyHMrW5Q06LspMnox7A="; includeSubDomains
562
723
```
563
724
564
725
[ `Agent` ] : #class-httpsagent
0 commit comments