summaryrefslogtreecommitdiffstats
path: root/ssl/t1_lib.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--ssl/t1_lib.c101
1 files changed, 68 insertions, 33 deletions
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 7f8fc5e615..d99384e289 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -400,6 +400,31 @@ int ssl_load_groups(SSL_CTX *ctx)
return OSSL_PROVIDER_do_all(ctx->libctx, discover_provider_groups, ctx);
}
+static uint16_t tls1_group_name2id(SSL_CTX *ctx, const char *name)
+{
+ size_t i;
+ int nid = NID_undef;
+
+ /* See if we can identify a nid for this name */
+#ifndef OPENSSL_NO_EC
+ nid = EC_curve_nist2nid(name);
+#endif
+ if (nid == NID_undef)
+ nid = OBJ_sn2nid(name);
+ if (nid == NID_undef)
+ nid = OBJ_ln2nid(name);
+
+ for (i = 0; i < ctx->group_list_len; i++) {
+ if (strcmp(ctx->group_list[i].tlsname, name) == 0
+ || (nid != NID_undef
+ && nid == tls1_group_id2nid(ctx->group_list[i].group_id,
+ 0)))
+ return ctx->group_list[i].group_id;
+ }
+
+ return 0;
+}
+
const TLS_GROUP_INFO *tls1_group_id_lookup(SSL_CTX *ctx, uint16_t group_id)
{
size_t i;
@@ -413,10 +438,13 @@ const TLS_GROUP_INFO *tls1_group_id_lookup(SSL_CTX *ctx, uint16_t group_id)
}
#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC)
-int tls1_group_id2nid(uint16_t group_id)
+int tls1_group_id2nid(uint16_t group_id, int include_unknown)
{
size_t i;
+ if (group_id == 0)
+ return NID_undef;
+
/*
* Return well known Group NIDs - for backwards compatibility. This won't
* work for groups we don't know about.
@@ -426,7 +454,9 @@ int tls1_group_id2nid(uint16_t group_id)
if (nid_to_group[i].group_id == group_id)
return nid_to_group[i].nid;
}
- return NID_undef;
+ if (!include_unknown)
+ return NID_undef;
+ return TLSEXT_nid_unknown | (int)group_id;
}
static uint16_t tls1_nid2group_id(int nid)
@@ -533,7 +563,7 @@ int tls_group_allowed(SSL *s, uint16_t group, int op)
gtmp[0] = group >> 8;
gtmp[1] = group & 0xff;
return ssl_security(s, op, ginfo->secbits,
- tls1_group_id2nid(ginfo->group_id), (void *)gtmp);
+ tls1_group_id2nid(ginfo->group_id, 0), (void *)gtmp);
}
/* Return 1 if "id" is in "list" */
@@ -655,60 +685,65 @@ err:
#endif /* !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) */
}
-#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
/* TODO(3.0): An arbitrary amount for now. Take another look at this */
# define MAX_GROUPLIST 40
typedef struct {
- size_t nidcnt;
- int nid_arr[MAX_GROUPLIST];
-} nid_cb_st;
+ SSL_CTX *ctx;
+ size_t gidcnt;
+ uint16_t gid_arr[MAX_GROUPLIST];
+} gid_cb_st;
-static int nid_cb(const char *elem, int len, void *arg)
+static int gid_cb(const char *elem, int len, void *arg)
{
- nid_cb_st *narg = arg;
+ gid_cb_st *garg = arg;
size_t i;
- int nid = NID_undef;
+ uint16_t gid = 0;
char etmp[20];
+
if (elem == NULL)
return 0;
- if (narg->nidcnt == MAX_GROUPLIST)
+ if (garg->gidcnt == MAX_GROUPLIST)
return 0;
if (len > (int)(sizeof(etmp) - 1))
return 0;
memcpy(etmp, elem, len);
etmp[len] = 0;
-# ifndef OPENSSL_NO_EC
- nid = EC_curve_nist2nid(etmp);
-# endif
- if (nid == NID_undef)
- nid = OBJ_sn2nid(etmp);
- if (nid == NID_undef)
- nid = OBJ_ln2nid(etmp);
- if (nid == NID_undef)
+
+ gid = tls1_group_name2id(garg->ctx, etmp);
+ if (gid == 0)
return 0;
- for (i = 0; i < narg->nidcnt; i++)
- if (narg->nid_arr[i] == nid)
+ for (i = 0; i < garg->gidcnt; i++)
+ if (garg->gid_arr[i] == gid)
return 0;
- narg->nid_arr[narg->nidcnt++] = nid;
+ garg->gid_arr[garg->gidcnt++] = gid;
return 1;
}
-#endif /* !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) */
-/* Set groups based on a colon separate list */
-int tls1_set_groups_list(uint16_t **pext, size_t *pextlen, const char *str)
+/* Set groups based on a colon separated list */
+int tls1_set_groups_list(SSL_CTX *ctx, uint16_t **pext, size_t *pextlen,
+ const char *str)
{
-#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
- nid_cb_st ncb;
- ncb.nidcnt = 0;
- if (!CONF_parse_list(str, ':', 1, nid_cb, &ncb))
+ gid_cb_st gcb;
+ uint16_t *tmparr;
+
+ gcb.gidcnt = 0;
+ gcb.ctx = ctx;
+ if (!CONF_parse_list(str, ':', 1, gid_cb, &gcb))
return 0;
if (pext == NULL)
return 1;
- return tls1_set_groups(pext, pextlen, ncb.nid_arr, ncb.nidcnt);
-#else
- return 0;
-#endif
+
+ /*
+ * gid_cb ensurse there are no duplicates so we can just go ahead and set
+ * the result
+ */
+ tmparr = OPENSSL_memdup(gcb.gid_arr, gcb.gidcnt * sizeof(*tmparr));
+ if (tmparr == NULL)
+ return 0;
+ *pext = tmparr;
+ *pextlen = gcb.gidcnt;
+ return 1;
}
/* Check a group id matches preferences */