@@ -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 ) => {
@@ -394,7 +456,33 @@ object, it will be automatically converted to an ordinary `options` object.
394
456
class. The ` ClientRequest ` instance is a writable stream. If one needs to
395
457
upload a file with a POST request, then write to the ` ClientRequest ` object.
396
458
397
- ``` js
459
+ ``` mjs
460
+ import { request } from ' node:https' ;
461
+ import process from ' node:process' ;
462
+
463
+ const options = {
464
+ hostname: ' encrypted.google.com' ,
465
+ port: 443 ,
466
+ path: ' /' ,
467
+ method: ' GET' ,
468
+ };
469
+
470
+ const req = request (options, (res ) => {
471
+ console .log (' statusCode:' , res .statusCode );
472
+ console .log (' headers:' , res .headers );
473
+
474
+ res .on (' data' , (d ) => {
475
+ process .stdout .write (d);
476
+ });
477
+ });
478
+
479
+ req .on (' error' , (e ) => {
480
+ console .error (e);
481
+ });
482
+ req .end ();
483
+ ```
484
+
485
+ ``` cjs
398
486
const https = require (' node:https' );
399
487
400
488
const options = {
@@ -427,8 +515,8 @@ const options = {
427
515
port: 443 ,
428
516
path: ' /' ,
429
517
method: ' GET' ,
430
- key: fs .readFileSync (' test/fixtures/keys/agent2 -key.pem' ),
431
- cert: fs .readFileSync (' test/fixtures/keys/agent2-cert .pem' ),
518
+ key: fs .readFileSync (' private -key.pem' ),
519
+ cert: fs .readFileSync (' certificate .pem' ),
432
520
};
433
521
options .agent = new https.Agent (options);
434
522
@@ -445,8 +533,8 @@ const options = {
445
533
port: 443 ,
446
534
path: ' /' ,
447
535
method: ' GET' ,
448
- key: fs .readFileSync (' test/fixtures/keys/agent2 -key.pem' ),
449
- cert: fs .readFileSync (' test/fixtures/keys/agent2-cert .pem' ),
536
+ key: fs .readFileSync (' private -key.pem' ),
537
+ cert: fs .readFileSync (' certificate .pem' ),
450
538
agent: false ,
451
539
};
452
540
@@ -468,7 +556,80 @@ const req = https.request(options, (res) => {
468
556
Example pinning on certificate fingerprint, or the public key (similar to
469
557
` pin-sha256 ` ):
470
558
471
- ``` js
559
+ ``` mjs
560
+ import { checkServerIdentity } from ' node:tls' ;
561
+ import { Agent , request } from ' node:https' ;
562
+ import { createHash } from ' node:crypto' ;
563
+
564
+ function sha256 (s ) {
565
+ return createHash (' sha256' ).update (s).digest (' base64' );
566
+ }
567
+ const options = {
568
+ hostname: ' github.com' ,
569
+ port: 443 ,
570
+ path: ' /' ,
571
+ method: ' GET' ,
572
+ checkServerIdentity : function (host , cert ) {
573
+ // Make sure the certificate is issued to the host we are connected to
574
+ const err = checkServerIdentity (host, cert);
575
+ if (err) {
576
+ return err;
577
+ }
578
+
579
+ // Pin the public key, similar to HPKP pin-sha256 pinning
580
+ const pubkey256 = ' SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8=' ;
581
+ if (sha256 (cert .pubkey ) !== pubkey256) {
582
+ const msg = ' Certificate verification error: ' +
583
+ ` The public key of '${ cert .subject .CN } ' ` +
584
+ ' does not match our pinned fingerprint' ;
585
+ return new Error (msg);
586
+ }
587
+
588
+ // Pin the exact certificate, rather than the pub key
589
+ const cert256 = ' FD:6E:9B:0E:F3:98:BC:D9:04:C3:B2:EC:16:7A:7B:' +
590
+ ' 0F:DA:72:01:C9:03:C5:3A:6A:6A:E5:D0:41:43:63:EF:65' ;
591
+ if (cert .fingerprint256 !== cert256) {
592
+ const msg = ' Certificate verification error: ' +
593
+ ` The certificate of '${ cert .subject .CN } ' ` +
594
+ ' does not match our pinned fingerprint' ;
595
+ return new Error (msg);
596
+ }
597
+
598
+ // This loop is informational only.
599
+ // Print the certificate and public key fingerprints of all certs in the
600
+ // chain. Its common to pin the public key of the issuer on the public
601
+ // internet, while pinning the public key of the service in sensitive
602
+ // environments.
603
+ let lastprint256;
604
+ do {
605
+ console .log (' Subject Common Name:' , cert .subject .CN );
606
+ console .log (' Certificate SHA256 fingerprint:' , cert .fingerprint256 );
607
+
608
+ const hash = createHash (' sha256' );
609
+ console .log (' Public key ping-sha256:' , sha256 (cert .pubkey ));
610
+
611
+ lastprint256 = cert .fingerprint256 ;
612
+ cert = cert .issuerCertificate ;
613
+ } while (cert .fingerprint256 !== lastprint256);
614
+
615
+ },
616
+ };
617
+
618
+ options .agent = new Agent (options);
619
+ const req = request (options, (res ) => {
620
+ console .log (' All OK. Server matched our pinned cert or public key' );
621
+ console .log (' statusCode:' , res .statusCode );
622
+
623
+ res .on (' data' , (d ) => {});
624
+ });
625
+
626
+ req .on (' error' , (e ) => {
627
+ console .error (e .message );
628
+ });
629
+ req .end ();
630
+ ```
631
+
632
+ ``` cjs
472
633
const tls = require (' node:tls' );
473
634
const https = require (' node:https' );
474
635
const crypto = require (' node:crypto' );
@@ -489,7 +650,7 @@ const options = {
489
650
}
490
651
491
652
// Pin the public key, similar to HPKP pin-sha256 pinning
492
- const pubkey256 = ' pL1+qb9HTMRZJmuC/bB/ZI9d302BYrrqiVuRyW+DGrU =' ;
653
+ const pubkey256 = ' SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8 =' ;
493
654
if (sha256 (cert .pubkey ) !== pubkey256) {
494
655
const msg = ' Certificate verification error: ' +
495
656
` The public key of '${ cert .subject .CN } ' ` +
@@ -498,8 +659,8 @@ const options = {
498
659
}
499
660
500
661
// Pin the exact certificate, rather than the pub key
501
- const cert256 = ' 25:FE:39:32:D9:63:8C:8A:FC:A1:9A:29:87 :' +
502
- ' D8:3E:4C:1D:98:DB:71:E4:1A:48:03:98:EA:22:6A:BD:8B:93:16 ' ;
662
+ const cert256 = ' FD:6E:9B:0E:F3:98:BC:D9:04:C3:B2:EC:16:7A:7B :' +
663
+ ' 0F:DA:72:01:C9:03:C5:3A:6A:6A:E5:D0:41:43:63:EF:65 ' ;
503
664
if (cert .fingerprint256 !== cert256) {
504
665
const msg = ' Certificate verification error: ' +
505
666
` The certificate of '${ cert .subject .CN } ' ` +
@@ -530,8 +691,6 @@ options.agent = new https.Agent(options);
530
691
const req = https .request (options, (res ) => {
531
692
console .log (' All OK. Server matched our pinned cert or public key' );
532
693
console .log (' statusCode:' , res .statusCode );
533
- // Print the HPKP values
534
- console .log (' headers:' , res .headers [' public-key-pins' ]);
535
694
536
695
res .on (' data' , (d ) => {});
537
696
});
@@ -546,17 +705,19 @@ Outputs for example:
546
705
547
706
``` text
548
707
Subject Common Name: github.com
549
- 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
550
- Public key ping-sha256: pL1+qb9HTMRZJmuC/bB/ZI9d302BYrrqiVuRyW+DGrU=
551
- Subject Common Name: DigiCert SHA2 Extended Validation Server CA
552
- 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
553
- Public key ping-sha256: RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=
554
- Subject Common Name: DigiCert High Assurance EV Root CA
555
- 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
556
- Public key ping-sha256: WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=
708
+ 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
709
+ Public key ping-sha256: SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8=
710
+ Subject Common Name: Sectigo ECC Domain Validation Secure Server CA
711
+ 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
712
+ Public key ping-sha256: Eep0p/AsSa9lFUH6KT2UY+9s1Z8v7voAPkQ4fGknZ2g=
713
+ Subject Common Name: USERTrust ECC Certification Authority
714
+ 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
715
+ Public key ping-sha256: UJM2FOhG9aTNY0Pg4hgqjNzZ/lQBiMGRxPD5Y2/e0bw=
716
+ Subject Common Name: AAA Certificate Services
717
+ 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
718
+ Public key ping-sha256: vRU+17BDT2iGsXvOi76E7TQMcTLXAqj0+jGPdW7L1vM=
557
719
All OK. Server matched our pinned cert or public key
558
720
statusCode: 200
559
- 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
560
721
```
561
722
562
723
[ `Agent` ] : #class-httpsagent
0 commit comments