Skip to content

Commit

Permalink
Set shared did methods
Browse files Browse the repository at this point in the history
  • Loading branch information
perubeanie committed Feb 9, 2024
1 parent 3c7a6b0 commit bc86e1d
Show file tree
Hide file tree
Showing 9 changed files with 197 additions and 20 deletions.
1 change: 0 additions & 1 deletion credential.jwt

This file was deleted.

4 changes: 3 additions & 1 deletion ssl/ssl_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -1644,6 +1644,8 @@ struct ssl_connection_st {
size_t didmethods_len;
/* our list */
uint16_t *didmethods;
/* used by the client to know if it actually sent did methods */
uint8_t didmethods_sent;

size_t peer_didmethods_len;
/* peer's list */
Expand Down Expand Up @@ -1839,7 +1841,7 @@ struct ssl_connection_st {
* DID methods shared by client and server: cached because these
* are used most often.
*/
const uint16_t *shared_didmethods;
const uint16_t **shared_didmethods;
size_t shared_didmethodslen;
#endif

Expand Down
118 changes: 116 additions & 2 deletions ssl/ssl_ssi.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,19 +177,133 @@ int ssl_setup_didmethods(SSL_CTX *ctx) {
}
#endif

#ifndef OPENSSL_NO_VCAUTHTLS
static int tls13_shared_didmethods(SSL_CONNECTION *s,
const uint16_t **shdidmethods,
const uint16_t *pref, size_t preflen,
const uint16_t *allow, size_t allowlen) {
const uint16_t *ptmp, *atmp;
size_t i, j, nmatch = 0;

for(i = 0, ptmp = pref; i < preflen; i++, ptmp++) {
for (j = 0, atmp = allow; j < allowlen; j++, atmp++) {
if (*ptmp == *atmp) {
nmatch++;
if (shdidmethods)
*shdidmethods++ = ptmp;
break;
}
}
}
return nmatch;
}
#endif

#ifndef OPENSSL_NO_VCAUTHTLS
static int tls13_check_shared_didmethods(SSL_CONNECTION *s,
const uint16_t *pref, size_t preflen,
const uint16_t *allow, size_t allowlen) {
const uint16_t *ptmp, *atmp;
size_t i, j;

for(i = 0, ptmp = pref; i < preflen; i++, ptmp++) {
for (j = 0, atmp = allow; j < allowlen; j++, atmp++) {
if (*ptmp == *atmp)
break;
}
if(j == allowlen)
return 0;
}

return 1;
}
#endif

#ifndef OPENSSL_NO_VCAUTHTLS
static int tls13_set_shared_didmethods(SSL_CONNECTION *s)
{
const uint16_t *pref, *allow;
const uint16_t **shdidmethods = NULL;
size_t preflen, allowlen;
size_t nmatch;

OPENSSL_free(s->shared_didmethods);
s->shared_didmethods = NULL;
s->shared_didmethodslen = 0;

pref = s->ext.peer_didmethods;
preflen = s->ext.peer_didmethods_len;
allow = s->ext.didmethods;
allowlen = s->ext.didmethods_len;

/* On client side check that each did method sent by the server belong to the client list */
if(!s->server)
if(!tls13_check_shared_didmethods(s, pref, preflen, allow, allowlen))
return 0;

nmatch = tls13_shared_didmethods(s, NULL, pref, preflen, allow, allowlen);
if (nmatch) {
if ((shdidmethods = OPENSSL_malloc(nmatch * sizeof(*shdidmethods))) == NULL)
return 0;
nmatch = tls13_shared_didmethods(s, shdidmethods, pref, preflen, allow, allowlen);
} else {
shdidmethods = NULL;
return 0; /* Maybe should be omitted */
}
s->shared_didmethods = shdidmethods;
s->shared_didmethodslen = nmatch;
return 1;
}
#endif

#ifndef OPENSSL_NO_VCAUTHTLS
int set_server_didmethods(SSL_CONNECTION *s) {

/* The server checks if the client sent the did_methods extension and set the
did_methods they have in common */

if(s->ext.client_cert_type != TLSEXT_cert_type_vc || !send_certificate_request(s))
return 1;

/* The server must have a list of did methods to send */
if(send_certificate_request(s) && s->ext.didmethods == NULL) {
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
SSL_R_TLSV13_ALERT_MISSING_EXTENSION);
return 0;
}
/* Some day MUST also be checked that the server's DID belongs to the list sent by the client */

/* If they both authenticate with VC the server must send a list of
did methods the two have in common. */
if(s->ext.server_cert_type == TLSEXT_cert_type_vc)
return tls13_set_shared_didmethods(s);

/* The server will send the full list of did methods */
return 1;
}
#endif

#ifndef OPENSSL_NO_VCAUTHTLS
int process_didmethods(SSL_CONNECTION *s) {

/* If client certificate type is set to VC the list sent by the server can't be empty */
if(s->ext.peer_didmethods == NULL) {
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
SSL_R_TLSV13_ALERT_MISSING_EXTENSION /* This should be changed to something more appropriate */);
return 0;
}

/* If the client sent the did methods extension checks that the list sent by the server
is a subset of its list */
if(s->ext.didmethods_sent) {
if(!tls13_set_shared_didmethods(s)) {
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
SSL_R_TLSV13_ALERT_MISSING_EXTENSION /* This should be changed to something more appropriate */);
return 0;
}
}

/* Otherwise accepts the whole list sent by the server */
/* Some day MUST also be checked that the client's DID belongs to the list sent by the server */

return 1;
}
#endif
3 changes: 2 additions & 1 deletion ssl/statem/extensions.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,8 @@ static const EXTENSION_DEFINITION ext_defs[] = {
TLSEXT_TYPE_did_methods,
SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_CERTIFICATE_REQUEST
| SSL_EXT_TLS1_3_ONLY,
NULL, tls_parse_ctos_did_methods, tls_parse_ctos_did_methods, tls_construct_stoc_did_methods, tls_construct_ctos_did_methods, NULL
NULL, tls_parse_ctos_did_methods, tls_parse_stoc_did_methods,
tls_construct_stoc_did_methods, tls_construct_ctos_did_methods, NULL
},
#else
INVALID_EXTENSION,
Expand Down
53 changes: 48 additions & 5 deletions ssl/statem/extensions_clnt.c
Original file line number Diff line number Diff line change
Expand Up @@ -2145,19 +2145,62 @@ EXT_RETURN tls_construct_ctos_did_methods(SSL_CONNECTION *sc, WPACKET *pkt,
unsigned int context,
X509 *x, size_t chainidx)
{
int i;
sc->ext.didmethods_sent = 0;

if(sc->ext.didmethods == NULL)
return EXT_RETURN_NOT_SENT;

if(!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_did_methods)
|| !WPACKET_start_sub_packet_u16(pkt)
/* || !WPACKET_start_sub_packet_u16(pkt) */
|| !WPACKET_sub_memcpy_u16(pkt, sc->ext.didmethods, sc->ext.didmethods_len*2)
|| !WPACKET_close(pkt)
/* || !WPACKET_close(pkt) */) {
|| !WPACKET_start_sub_packet_u16(pkt)) {
SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
}

for (i = 0; i < sc->ext.didmethods_len; i++) {
if(!WPACKET_put_bytes_u16(pkt, sc->ext.didmethods[i])) {
SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
}
}

if (!WPACKET_close(pkt)
|| !WPACKET_close(pkt)) {
SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
}

sc->ext.didmethods_sent = 1;
return EXT_RETURN_SENT;
}
#endif

#ifndef OPENSSL_NO_VCAUTHTLS
int tls_parse_stoc_did_methods(SSL_CONNECTION *sc, PACKET *pkt,
unsigned int context,
X509 *x, size_t chainidx)
{
PACKET did_methods;

/* Ignore the extension */
if(sc->ext.client_cert_type != TLSEXT_cert_type_vc)
return 1;

if(!PACKET_as_length_prefixed_2(pkt, &did_methods)
|| PACKET_remaining(&did_methods) == 0) {
SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
return 0;
}

OPENSSL_free(sc->ext.peer_didmethods);
sc->ext.peer_didmethods = NULL;
sc->ext.peer_didmethods_len = 0;
if (!tls1_save_u16(&did_methods, &sc->ext.peer_didmethods,
&sc->ext.peer_didmethods_len)) {
SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}

return 1;
}
#endif
23 changes: 19 additions & 4 deletions ssl/statem/extensions_srvr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2121,6 +2121,10 @@ int tls_parse_ctos_did_methods(SSL_CONNECTION *sc, PACKET *pkt,
{
PACKET did_methods;

/* Ignore the extension */
if(sc->ext.server_cert_type != TLSEXT_cert_type_vc)
return 1;

if(!PACKET_as_length_prefixed_2(pkt, &did_methods)
|| PACKET_remaining(&did_methods) == 0) {
SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
Expand All @@ -2147,14 +2151,15 @@ EXT_RETURN tls_construct_stoc_did_methods (SSL_CONNECTION *sc, WPACKET *pkt,
{
const uint16_t *didmethods;
size_t didmethodslen;
int i;

if(sc->ext.client_cert_type != TLSEXT_cert_type_vc
|| sc->ext.didmethods == NULL)
return EXT_RETURN_NOT_SENT;

if (sc->shared_didmethods != NULL)
{
didmethods = sc->shared_didmethods;
didmethods = *sc->shared_didmethods;
didmethodslen = sc->shared_didmethodslen;
}
else
Expand All @@ -2165,9 +2170,19 @@ EXT_RETURN tls_construct_stoc_did_methods (SSL_CONNECTION *sc, WPACKET *pkt,

if(!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_did_methods)
|| !WPACKET_start_sub_packet_u16(pkt)
/* || !WPACKET_start_sub_packet_u16(pkt) */
|| !WPACKET_sub_memcpy_u16(pkt, didmethods, didmethodslen*2)
/* || !WPACKET_close(pkt) */
|| !WPACKET_start_sub_packet_u16(pkt)) {
SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
}

for(i = 0; i < didmethodslen; i++) {
if(!WPACKET_put_bytes_u16(pkt, didmethods[i])) {
SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
}
}

if(!WPACKET_close(pkt)
|| !WPACKET_close(pkt)) {
SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
Expand Down
9 changes: 5 additions & 4 deletions ssl/statem/statem_clnt.c
Original file line number Diff line number Diff line change
Expand Up @@ -2666,10 +2666,11 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL_CONNECTION *s,
return MSG_PROCESS_ERROR;
}
#ifndef OPENSSL_NO_VCAUTHTLS
if (!process_didmethods(s)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_LENGTH);
return MSG_PROCESS_ERROR;
}
if(s->ext.client_cert_type == TLSEXT_cert_type_vc)
if (!process_didmethods(s)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_LENGTH);
return MSG_PROCESS_ERROR;
}
#endif
} else {
PACKET ctypes;
Expand Down
3 changes: 1 addition & 2 deletions ssl/statem/statem_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -1138,10 +1138,9 @@ int tls_process_vc(SSL_CONNECTION *sc, PACKET *pkt, EVP_PKEY **peer_rpk)
EVP_PKEY *pkey = NULL;
int ret = 0;
RAW_EXTENSION *rawexts = NULL;
PACKET extensions;
PACKET context;
unsigned long cert_len = 0, spki_len = 0;
const unsigned char *spki, *spkistart;
const unsigned char *spki;
SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(sc);

if (SSL_CONNECTION_IS_TLS13(sc)) {
Expand Down
3 changes: 3 additions & 0 deletions ssl/statem/statem_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,9 @@ __owur int tls_process_vc(SSL_CONNECTION *sc, PACKET *pkt, EVP_PKEY **peer_vc);
__owur EXT_RETURN tls_construct_ctos_did_methods(SSL_CONNECTION *sc, WPACKET *pkt,
unsigned int context,
X509 *x, size_t chainidx);
__owur int tls_parse_stoc_did_methods(SSL_CONNECTION *sc, PACKET *pkt,
unsigned int context,
X509 *x, size_t chainidx);
__owur int tls_parse_ctos_did_methods(SSL_CONNECTION *sc, PACKET *pkt,
unsigned int context,
X509 *x, size_t chainidx);
Expand Down

0 comments on commit bc86e1d

Please sign in to comment.