Skip to content

Commit

Permalink
certmap: add support for SID extension
Browse files Browse the repository at this point in the history
Check if the SID extension is available, read the SID and make it
available.

Resolves: SSSD#6403

Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
Reviewed-by: Justin Stephenson <jstephen@redhat.com>
  • Loading branch information
sumit-bose authored and alexey-tikhonov committed Dec 2, 2022
1 parent 10d977a commit 9e1b711
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 0 deletions.
134 changes: 134 additions & 0 deletions src/lib/certmap/sss_cert_content_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
#define X509_get_key_usage(o) ((o)->ex_kusage)
#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */

#define OID_NTDS_CA_SECURITY_EXT "1.3.6.1.4.1.311.25.2"
#define OID_NTDS_OBJECTSID "1.3.6.1.4.1.311.25.2.1"

typedef struct PrincipalName_st {
ASN1_INTEGER *name_type;
STACK_OF(ASN1_GENERALSTRING) *name_string;
Expand All @@ -65,6 +68,44 @@ ASN1_SEQUENCE(KRB5PrincipalName) = {

IMPLEMENT_ASN1_FUNCTIONS(KRB5PrincipalName)

/* Microsoft's CA Security Extension as described in section 2.2.2.7.7.4 of
* [MS-WCCE]: Windows Client Certificate Enrollment Protocol
* https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wcce/e563cff8-1af6-4e6f-a655-7571ca482e71
*/
typedef struct NTDS_OBJECTSID_st {
ASN1_OBJECT *type_id;
ASN1_OCTET_STRING *value;
} NTDS_OBJECTSID;

ASN1_SEQUENCE(NTDS_OBJECTSID) = {
ASN1_SIMPLE(NTDS_OBJECTSID, type_id, ASN1_OBJECT),
ASN1_EXP(NTDS_OBJECTSID, value, ASN1_OCTET_STRING, 0)
} ASN1_SEQUENCE_END(NTDS_OBJECTSID)

IMPLEMENT_ASN1_FUNCTIONS(NTDS_OBJECTSID)

typedef struct NTDS_CA_SECURITY_EXT_st {
#define NTDS_CA_SECURITY_EXT_OBJECTSID 0
int type;
union {
NTDS_OBJECTSID *sid;
} d;
} NTDS_CA_SECURITY_EXT;

ASN1_CHOICE(NTDS_CA_SECURITY_EXT) = {
ASN1_IMP(NTDS_CA_SECURITY_EXT, d.sid, NTDS_OBJECTSID, NTDS_CA_SECURITY_EXT_OBJECTSID)
} ASN1_CHOICE_END(NTDS_CA_SECURITY_EXT)

IMPLEMENT_ASN1_FUNCTIONS(NTDS_CA_SECURITY_EXT)

typedef STACK_OF(NTDS_CA_SECURITY_EXT) NTDS_CA_SECURITY_EXTS;

ASN1_ITEM_TEMPLATE(NTDS_CA_SECURITY_EXTS) =
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, SecExts, NTDS_CA_SECURITY_EXT)
ASN1_ITEM_TEMPLATE_END(NTDS_CA_SECURITY_EXTS)

IMPLEMENT_ASN1_FUNCTIONS(NTDS_CA_SECURITY_EXTS)

enum san_opt openssl_name_type_to_san_opt(int type)
{
switch (type) {
Expand Down Expand Up @@ -651,6 +692,94 @@ static int get_san(TALLOC_CTX *mem_ctx, X509 *cert, struct san_list **san_list)
return ret;
}

static int get_sid_ext(TALLOC_CTX *mem_ctx, X509 *cert, const char **_sid)
{
int ret;
ASN1_OBJECT *sid_ext_oid = NULL;
ASN1_OBJECT *sid_oid = NULL;
int idx;
X509_EXTENSION *ext = NULL;
const unsigned char *p;
NTDS_CA_SECURITY_EXTS *sec_exts = NULL;
NTDS_CA_SECURITY_EXT *current;
char *sid = NULL;
const ASN1_OCTET_STRING *ext_data = NULL;
size_t c;

sid_ext_oid = OBJ_txt2obj(OID_NTDS_CA_SECURITY_EXT, 1);
if (sid_ext_oid == NULL) {
return EIO;
}

idx = X509_get_ext_by_OBJ(cert, sid_ext_oid, -1);
ASN1_OBJECT_free(sid_ext_oid);
if (idx == -1) {
/* Extension most probably not available, no error. */
return 0;
}

ext = X509_get_ext(cert, idx);
if (ext == NULL) {
return EINVAL;
}

ext_data = X509_EXTENSION_get_data(ext);
if (ext_data == NULL) {
return EINVAL;
}

p = ext_data->data;
sec_exts = d2i_NTDS_CA_SECURITY_EXTS(NULL, &p, ext_data->length);
if (sec_exts == NULL) {
return EIO;
}

ret = EINVAL;
for (c = 0; c < OPENSSL_sk_num((const OPENSSL_STACK *) sec_exts); c++) {
current = (NTDS_CA_SECURITY_EXT *)
OPENSSL_sk_value((const OPENSSL_STACK *) sec_exts, c);
/* Only handle NTDS_CA_SECURITY_EXT_OBJECTSID. So far no other types
* are defined. */
if (current->type == NTDS_CA_SECURITY_EXT_OBJECTSID) {
if (sid != NULL) {
/* second SID found, currently not expected */
talloc_free(sid);
ret = EINVAL;
goto done;
}

sid_oid = OBJ_txt2obj(OID_NTDS_OBJECTSID, 1);
if (sid_oid == NULL) {
ret = EIO;
goto done;
}
if (current->d.sid->type_id == NULL
|| OBJ_cmp(current->d.sid->type_id, sid_oid) != 0) {
/* Unexpected OID */
ret = EINVAL;
goto done;
}

sid = talloc_strndup(mem_ctx, (char *) current->d.sid->value->data,
current->d.sid->value->length);
if (sid == NULL) {
ret = ENOMEM;
goto done;
}
ret = 0;
}
}

done:
NTDS_CA_SECURITY_EXTS_free(sec_exts);
ASN1_OBJECT_free(sid_oid);

if (ret == 0) {
*_sid = sid;
}
return ret;
}

static int get_extended_key_usage_oids(TALLOC_CTX *mem_ctx,
X509 *cert,
const char ***_oids)
Expand Down Expand Up @@ -915,6 +1044,11 @@ int sss_cert_get_content(TALLOC_CTX *mem_ctx,
goto done;
}

ret = get_sid_ext(cont, cert, &(cont->sid_ext));
if (ret != 0) {
goto done;
}

cont->cert_der = talloc_memdup(cont, der_blob, der_size);
if (cont->cert_der == NULL) {
ret = ENOMEM;
Expand Down
2 changes: 2 additions & 0 deletions src/lib/certmap/sss_certmap_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,8 @@ struct sss_cert_content {

uint8_t *subject_key_id;
size_t subject_key_id_size;

const char *sid_ext;
};

int sss_cert_get_content(TALLOC_CTX *mem_ctx,
Expand Down

0 comments on commit 9e1b711

Please sign in to comment.