@@ -176,6 +176,24 @@ failure. When an s2n function returns a failure, s2n_errno will be set to a valu
176
176
corresponding to the error. This error value can be translated into a string
177
177
explaining the error by calling s2n_strerror(s2n_errno, "EN");
178
178
179
+ ## Initialization and teardown
180
+
181
+ ### s2n\_ init
182
+
183
+ int s2n_init();
184
+
185
+ ** s2n_init** initializes the s2n library and should be called once in your application,
186
+ before any other s2n functions are called. Failure to call s2n_init() will result
187
+ in errors from other s2n functions.
188
+
189
+ ### s2n\_ cleanup
190
+
191
+ int s2n_cleanup();
192
+
193
+ ** s2n_cleanup** cleans up any internal resources used by s2n. This function should be
194
+ called from each thread or process that is created subsequent to calling ** s2n_init**
195
+ when that thread or process is done calling other s2n functions.
196
+
179
197
## Configuration-oriented functions
180
198
181
199
### s2n\_ config\_ new
@@ -452,7 +470,7 @@ connection. **s2n_recv** will return the number of bytes read and also return
452
470
break;
453
471
}
454
472
bytes_read += r;
455
- } while (more);
473
+ } while (more);
456
474
457
475
### s2n_shutdown
458
476
@@ -463,197 +481,5 @@ connection. **s2n_recv** will return the number of bytes read and also return
463
481
464
482
# Examples
465
483
466
- To understand the API it may be easiest to see examples in action.
467
-
468
- ## Example server
469
-
470
- This example server reads a single HTTP request (over HTTPS) and then responds with a trivial HTML response.
471
-
472
- #include <sys/types.h>
473
- #include <sys/socket.h>
474
- #include <sys/ioctl.h>
475
- #include <sys/poll.h>
476
- #include <netdb.h>
477
-
478
- #include <stdlib.h>
479
- #include <unistd.h>
480
- #include <string.h>
481
- #include <stdio.h>
482
-
483
- #include <errno.h>
484
-
485
- #include <s2n.h>
486
-
487
- static char certificate[] =
488
- "-----BEGIN CERTIFICATE-----\n"
489
- "MIIDLjCCAhYCCQDL1lr6N8/gvzANBgkqhkiG9w0BAQUFADBZMQswCQYDVQQGEwJB\n"
490
- "VTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0\n"
491
- "cyBQdHkgTHRkMRIwEAYDVQQDEwlsb2NhbGhvc3QwHhcNMTQwNTEwMTcwODIzWhcN\n"
492
- "MjQwNTA3MTcwODIzWjBZMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0\n"
493
- "ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRIwEAYDVQQDEwls\n"
494
- "b2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIltaUmHg+\n"
495
- "G7Ida2XCtEQx1YeWDX41U2zBKbY0lT+auXf81cT3dYTdfJblb+v4CTWaGNofogcz\n"
496
- "ebm8B2/OF9F+WWkKAJhKsTPAE7/SNAdi4Eqv4FfNbWKkGb4xacxxb4PH2XP9V3Ch\n"
497
- "J6lMSI3V68FmEf4kcEN14V8vufIC5HE/LT4gCPDJ4UfUUbAgEhSebT6r/KFYB5T3\n"
498
- "AeDc1VdnaaRblrP6KwM45vTs0Ii09/YrlzBxaTPMjLGCKa8JMv8PW2R0U9WCqHmz\n"
499
- "BH+W3Q9xPrfhCInm4JWob8WgM1NuiYuzFB0CNaQcdMS7h0aZEAVnayhQ96/Padpj\n"
500
- "KNE0Lur9nUxbAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAGRV71uRt/1dADsMD9fg\n"
501
- "JvzW89jFAN87hXCRhTWxfXhYMzknxJ5WMb2JAlaMc/gTpiDiQBkbvB+iJe5AepgQ\n"
502
- "WbyxPJNtSlA9GfKBz1INR5cFsOL27VrBoMYHMaolveeslc1AW2HfBtXWXeWSEF7F\n"
503
- "QNgye8ZDPNzeSWSI0VyK2762wsTgTuUhHAaJ45660eX57+e8IvaM7xOEfBPDKYtU\n"
504
- "0a28ZuhvSr2akJtGCwcs2J6rs6I+rV84UktDxFC9LUezBo8D9FkMPLoPKKNH1dXR\n"
505
- "6LO8GOkqWUrhPIEmfy9KYes3q2ZX6svk4rwBtommHRv30kPxnnU1YXt52Ri+XczO\n"
506
- "wEs=\n"
507
- "-----END CERTIFICATE-----\n";
508
-
509
- static char private_key[] =
510
- "-----BEGIN RSA PRIVATE KEY-----\n"
511
- "MIIEpAIBAAKCAQEAyJbWlJh4PhuyHWtlwrREMdWHlg1+NVNswSm2NJU/mrl3/NXE\n"
512
- "93WE3XyW5W/r+Ak1mhjaH6IHM3m5vAdvzhfRfllpCgCYSrEzwBO/0jQHYuBKr+BX\n"
513
- "zW1ipBm+MWnMcW+Dx9lz/VdwoSepTEiN1evBZhH+JHBDdeFfL7nyAuRxPy0+IAjw\n"
514
- "yeFH1FGwIBIUnm0+q/yhWAeU9wHg3NVXZ2mkW5az+isDOOb07NCItPf2K5cwcWkz\n"
515
- "zIyxgimvCTL/D1tkdFPVgqh5swR/lt0PcT634QiJ5uCVqG/FoDNTbomLsxQdAjWk\n"
516
- "HHTEu4dGmRAFZ2soUPevz2naYyjRNC7q/Z1MWwIDAQABAoIBAHrkryLrJwAmR8Hu\n"
517
- "grH/b6h4glFUgvZ43jCaNZ+RsR5Cc1jcP4i832Izat+26oNUYRrADyNCSdcnxLuG\n"
518
- "cuF5hkg6zzfplWRtnJ8ZenR2m+/gKuIGOMULN1wCyZvMjg0RnVNbzsxwPfj+K6Mo\n"
519
- "8H0Xq621aFc60JnwMjkzWyqaeyeQogn1pqybuL6Dm2huvN49LR64uHuDUStTRX33\n"
520
- "ou1fVWXOJ1kealYPbRPj8pDa31omB8q5Cf8Qe/b9anqyi9CsP17QbVg9k2IgoLlj\n"
521
- "agqOc0u/opOTZB4tqJbqsIdEhc5LD5RUkYJsw00Iq0RSiKTfiWSPyOFw99Y9Act0\n"
522
- "cbIIxEECgYEA8/SOsQjoUX1ipRvPbfO3suV1tU1hLCQbIpv7WpjNr1kHtngjzQMP\n"
523
- "dU/iriUPGF1H+AxJJcJQfCVThV1AwFYVKb/LCrjaxlneZSbwfehpjo+xQGaNYG7Q\n"
524
- "1vQuBVejuYk/IvpZltQOdm838DjvYyWDMh4dcMFIycXxEg+oHxf/s+8CgYEA0n4p\n"
525
- "GBuLUNx9vv3e84BcarLaOF7wY7tb8z2oC/mXztMZpKjovTH0PvePgI5/b3KQ52R0\n"
526
- "8zXHVX/4lSQVtCuhOVwKOCQq97/Zhlp5oTTShdQ0Qa1GQRl5wbTS6hrYEWSi9AQP\n"
527
- "BVUPZ+RIcxx00DfBNURkId8xEpvCOmvySN8sUlUCgYAtXmHbEqkB3qulwRJGhHi5\n"
528
- "UGsfmJBlwSE6wn9wTdKStZ/1k0o1KkiJrJ2ffUzdXxuvSbmgyA5nyBlMSBdurZOp\n"
529
- "+/0qtU4abUQq058OC1b2KEryix/nuzQjha25WJ8eNiQDwUNABZfa9rwUdMIwUh2g\n"
530
- "CHG5Mnjy7Vjz3u2JOtFXCQKBgQCVRo1EIHyLauLuaMINM9HWhWJGqeWXBM8v0GD1\n"
531
- "pRsovQKpiHQNgHizkwM861GqqrfisZZSyKfFlcynkACoVmyu7fv9VoD2VCMiqdUq\n"
532
- "IvjNmfE5RnXVQwja+668AS+MHi+GF77DTFBxoC5VHDAnXfLyIL9WWh9GEBoNLnKT\n"
533
- "hVm8RQKBgQCB9Skzdftc+14a4Vj3NCgdHZHz9mcdPhzJXUiQyZ3tYhaytX9E8mWq\n"
534
- "pm/OFqahbxw6EQd86mgANBMKayD6B1Id1INqtXN1XYI50bSs1D2nOGsBM7MK9aWD\n"
535
- "JXlJ2hwsIc4q9En/LR3GtBaL84xTHGfznNylNhXi7GbO1wNMJuAukA==\n"
536
- "-----END RSA PRIVATE KEY-----\n";
537
-
538
- static char dhparams[] =
539
- "-----BEGIN DH PARAMETERS-----\n"
540
- "MIIBCAKCAQEAy1+hVWCfNQoPB+NA733IVOONl8fCumiz9zdRRu1hzVa2yvGseUSq\n"
541
- "Bbn6k0FQ7yMED6w5XWQKDC0z2m0FI/BPE3AjUfuPzEYGqTDf9zQZ2Lz4oAN90Sud\n"
542
- "luOoEhYR99cEbCn0T4eBvEf9IUtczXUZ/wj7gzGbGG07dLfT+CmCRJxCjhrosenJ\n"
543
- "gzucyS7jt1bobgU66JKkgMNm7hJY4/nhR5LWTCzZyzYQh2HM2Vk4K5ZqILpj/n0S\n"
544
- "5JYTQ2PVhxP+Uu8+hICs/8VvM72DznjPZzufADipjC7CsQ4S6x/ecZluFtbb+ZTv\n"
545
- "HI5CnYmkAwJ6+FSWGaZQDi8bgerFk9RWwwIBAg==\n"
546
- "-----END DH PARAMETERS-----\n";
547
-
548
- static char response[] =
549
- "HTTP/1.0 200 OK\r\n"
550
- "Content-Length: 34\r\n"
551
- "Connection: close\r\n"
552
- "Content-Type: text/html; charset=utf-8\r\n\r\n"
553
- "<html><h1>Hello World!</h1></html>";
554
-
555
- void usage()
556
- {
557
- fprintf(stderr, "usage: example_https_server ip port\n");
558
- fprintf(stderr, " host: hostname or IP address to listen on\n");
559
- fprintf(stderr, " port: hostname or IP address to listen on\n");
560
-
561
- exit(1);
562
- }
563
-
564
- int main(int argc, const char *argv[])
565
- {
566
- struct addrinfo hints, *ai;
567
- int r, sockfd = 0;
568
- int more;
569
-
570
- if (argc != 3) {
571
- usage();
572
- }
573
-
574
- if (memset(&hints, 0, sizeof(hints)) != &hints) {
575
- fprintf(stderr, "memset error: %s\n", strerror(errno));
576
- return -1;
577
- }
578
-
579
- hints.ai_family = AF_UNSPEC;
580
- hints.ai_socktype = SOCK_STREAM;
581
-
582
- if ((r = getaddrinfo(argv[1], argv[2], &hints, &ai)) != 0) {
583
- fprintf(stderr, "error: %s\n", gai_strerror(r));
584
- return -1;
585
- }
586
-
587
- if ((sockfd = socket(ai->ai_family, ai->ai_socktype,
588
- ai->ai_protocol)) == -1) {
589
- exit(1);
590
- }
591
-
592
- r = 1;
593
- if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &r, sizeof(int)) < 0) {
594
- exit(1);
595
- }
596
-
597
- if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
598
- exit(1);
599
- }
600
-
601
- if (listen(sockfd, 1) == -1) {
602
- exit(1);
603
- }
604
- struct s2n_config *config = s2n_config_new();
605
- if (!config) {
606
- fprintf(stderr, "Error getting new s2n config: '%s'\n", s2n_strerror(s2n_errno, "EN"));
607
- exit(1);
608
- }
609
-
610
- if (s2n_config_add_cert_chain_and_key(config, "_default_", certificate,
611
- private_key) < 0) {
612
- fprintf(stderr, "Error getting certificate/key: '%s'\n", s2n_strerror(s2n_errno, "EN"));
613
- exit(1);
614
- }
615
-
616
- if (s2n_config_add_dhparams(config, dhparams) < 0) {
617
- fprintf(stderr, "Error adding DH parameters: '%s'\n", s2n_strerror(s2n_errno, "EN"));
618
- exit(1);
619
- }
620
-
621
- struct s2n_connection *conn = s2n_connection_new(S2N_SERVER);
622
-
623
- if (s2n_connection_set_config(conn, config) < 0) {
624
- fprintf(stderr, "Error setting configuration: '%s'\n", s2n_strerror(s2n_errno, "EN"));
625
- exit(1);
626
- }
627
-
628
- int fd;
629
- while ((fd = accept(sockfd, ai->ai_addr, &ai->ai_addrlen)) > 0) {
630
- if (s2n_connection_set_fd(conn, fd) < 0) {
631
- fprintf(stderr, "Error setting file descriptor: '%s'\n", s2n_strerror(s2n_errno, "EN"));
632
- exit(1);
633
- }
634
-
635
- if (s2n_negotiate(conn, &more) < 0) {
636
- fprintf(stderr, "Error negotiating: '%s'\n", s2n_strerror(s2n_errno, "EN"));
637
- s2n_connection_wipe(conn);
638
- continue;
639
- }
640
-
641
- if (s2n_get_server_name(conn)) {
642
- printf("Got connection with server name: '%s'\n",
643
- s2n_get_server_name(conn));
644
- }
645
- else {
646
- printf("Got connection with no server name\n");
647
- }
648
-
649
- if (s2n_send(conn, response, sizeof(response), &more) < 0) {
650
- s2n_connection_wipe(conn);
651
- continue;
652
- }
653
-
654
- s2n_shutdown(conn, &more);
655
- s2n_connection_wipe(conn);
656
- }
657
-
658
- return 0;
659
- }
484
+ To understand the API it may be easiest to see examples in action. s2n's [ bin/] ( https://github.com/awslabs/s2n/blob/master/bin/ ) directory
485
+ includes an example client (s2nc) and server (s2nd)..
0 commit comments