Skip to content

Commit 966deac

Browse files
Add CertificateRequest certificate selection callback (#5318)
Co-authored-by: Sam Clark <3758302+goatgoose@users.noreply.github.com>
1 parent 4a895ba commit 966deac

File tree

10 files changed

+492
-64
lines changed

10 files changed

+492
-64
lines changed

api/unstable/cert_authorities.h

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
/**
17+
* @file cert_authorities.h
18+
*
19+
* This contains unstable APIs for selecting a client-sent certificate in
20+
* response to the CertificateRequest message, and the necessary server-side
21+
* work to support that selection (currently, just certificate_authorities).
22+
*
23+
* See also https://github.com/aws/s2n-tls/issues/5330. Please comment there if
24+
* you're using the feature and report back on your experience.
25+
*/
26+
27+
#pragma once
28+
29+
#include <s2n.h>
30+
#include <stdbool.h>
31+
#include <stdint.h>
32+
#include <stdio.h>
33+
#include <sys/types.h>
34+
#include <sys/uio.h>
35+
36+
struct s2n_certificate_request;
37+
struct s2n_certificate_authority_list;
38+
39+
/**
40+
* Get the certificate_authorities list from the certificate request.
41+
*
42+
* @returns The list, with a lifetime equivalent to the s2n_certificate_request.
43+
* This points into the certificate request (it is not a copy of the list).
44+
* Can be null if the list is not available.
45+
*/
46+
S2N_API struct s2n_certificate_authority_list *s2n_certificate_request_get_ca_list(struct s2n_certificate_request *request);
47+
48+
/**
49+
* Sets the certificate chain to return in response to the certificate request.
50+
*
51+
* @param chain must outlive the connection being served.
52+
*
53+
* @warning It is not recommended to free or modify the `chain`. It must
54+
* outlive this connection.
55+
*
56+
* @returns S2N_SUCCESS on success. S2N_FAILURE on failure
57+
*/
58+
S2N_API int s2n_certificate_request_set_certificate(struct s2n_certificate_request *request, struct s2n_cert_chain_and_key *chain);
59+
60+
/**
61+
* Checks whether the offered list has a next entry.
62+
*
63+
* @param list A pointer to the certificate authority list being read.
64+
* @returns bool If true, there is a next entry.
65+
*/
66+
S2N_API bool s2n_certificate_authority_list_has_next(struct s2n_certificate_authority_list *list);
67+
68+
/**
69+
* Obtains the next entry in the certificate authority list.
70+
*
71+
* The lifetime of the name is bound to the lifetime of the list (in other
72+
* words, it must not be used past the certificate request callback).
73+
*
74+
* The name contains the bytes sent by the server. This should be a DER-encoded
75+
* DistinguishedName, but s2n-tls does not currently strictly enforce the
76+
* contents of the parsed name.
77+
*
78+
* See https://tools.ietf.org/rfc/rfc8446#section-4.2.4.
79+
*
80+
* @param list A pointer to the list being read.
81+
* @param name An out-pointer to the next name in the list.
82+
* @param length An out-pointer which is initialized to the length of the next name.
83+
*
84+
* @returns S2N_SUCCESS on success. S2N_FAILURE on failure
85+
*/
86+
S2N_API int s2n_certificate_authority_list_next(struct s2n_certificate_authority_list *list, uint8_t **name, uint16_t *length);
87+
88+
/**
89+
* Returns the certificate authority list to its original state.
90+
*
91+
* When `s2n_certificate_authority_list_reread` is called, the list is reset to the beginning.
92+
*
93+
* @param list The list to re-read.
94+
*/
95+
S2N_API int s2n_certificate_authority_list_reread(struct s2n_certificate_authority_list *list);
96+
97+
/* CertificateRequest callback.
98+
*
99+
* @param conn The connection object for the in-progress connection.
100+
* @param ctx A pointer to a user defined context provided in s2n_config_set_cert_request_callback.
101+
* @param request CertificateRequest, containing metadata about the incoming
102+
* request and a setter for the certificate to use.
103+
* @returns S2N_SUCCESS on success. S2N_FAILURE on failure
104+
*/
105+
typedef int (*s2n_cert_request_callback)(struct s2n_connection *conn, void *ctx, struct s2n_certificate_request *request);
106+
107+
/* Allows the caller to set a callback function that will be called after
108+
* CertificateRequest message is parsed.
109+
*
110+
* This is currently only called on the client side.
111+
*
112+
* @param config A pointer to the s2n_config object.
113+
* @param cert_req_callback The callback to be invoked.
114+
* @param ctx A pointer to a user defined context to be sent to `cert_req_callback`.
115+
* @returns S2N_SUCCESS on success. S2N_FAILURE on failure.
116+
*/
117+
S2N_API int s2n_config_set_cert_request_callback(struct s2n_config *config, s2n_cert_request_callback cert_req_callback, void *ctx);

bindings/rust/extended/s2n-tls-sys/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ fips = ["aws-lc-rs/fips"]
3131
pq = []
3232
internal = []
3333
stacktrace = []
34+
unstable-cert_authorities = []
3435
unstable-cleanup = []
3536
unstable-crl = []
3637
unstable-fingerprint = []

tests/unit/s2n_cert_authorities_test.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,5 +402,21 @@ int main(int argc, char **argv)
402402
}
403403
};
404404

405+
/* Safety Test: s2n_certificate_request_get_ca_list */
406+
{
407+
EXPECT_NULL(s2n_certificate_request_get_ca_list(NULL));
408+
};
409+
410+
/* Safety Test: s2n_certificate_request_set_certificate */
411+
{
412+
/* Note: NULL for the 2nd argument is tested in s2n_mutual_auth. */
413+
EXPECT_FAILURE_WITH_ERRNO(s2n_certificate_request_set_certificate(NULL, NULL), S2N_ERR_INVALID_ARGUMENT);
414+
};
415+
416+
/* Safety Test: s2n_certificate_authority_list_has_next */
417+
{
418+
EXPECT_FALSE(s2n_certificate_authority_list_has_next(NULL));
419+
};
420+
405421
END_TEST();
406422
}

0 commit comments

Comments
 (0)