31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose SSSD - certificate handling utils - OpenSSL version
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose The calls defined here should be useable outside of SSSD as well, e.g. in
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose libsss_certmap.
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose Copyright (C) Sumit Bose <sbose@redhat.com> 2017
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose This program is free software; you can redistribute it and/or modify
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose it under the terms of the GNU General Public License as published by
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose the Free Software Foundation; either version 3 of the License, or
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose (at your option) any later version.
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose This program is distributed in the hope that it will be useful,
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose but WITHOUT ANY WARRANTY; without even the implied warranty of
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose GNU General Public License for more details.
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose You should have received a copy of the GNU General Public License
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose along with this program. If not, see <http://www.gnu.org/licenses/>.
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose/* backward compatible macros for OpenSSL < 1.1 */
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose#define ASN1_STRING_get0_data(o) ASN1_STRING_data(o)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose#define X509_get_extension_flags(o) ((o)->ex_flags)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_EXP(PrincipalName, name_type, ASN1_INTEGER, 0),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_EXP_SEQUENCE_OF(PrincipalName, name_string, ASN1_GENERALSTRING, 1)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_EXP(KRB5PrincipalName, realm, ASN1_GENERALSTRING, 0),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_EXP(KRB5PrincipalName, principal_name, PrincipalName, 1)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Boseenum san_opt openssl_name_type_to_san_opt(int type)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosestatic int add_string_other_name_to_san_list(TALLOC_CTX *mem_ctx,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose char oid_buf[128]; /* FIXME: any other size ?? */
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose unsigned char *p;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose len = OBJ_obj2txt(oid_buf, sizeof(oid_buf), other_name->type_id, 1);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i->other_name_oid = talloc_strndup(i, oid_buf, len);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose /* i2d_TYPE increment the second argument so that it points to the end of
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose * the written data hence we cannot use i->bin_val directly. */
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i->bin_val_len = i2d_ASN1_TYPE(other_name->value, &p);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosestatic int add_nt_princ_to_san_list(TALLOC_CTX *mem_ctx,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ASN1_TYPE_get(other_name->value) != V_ASN1_UTF8STRING) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_STRING_length(other_name->value->value.utf8string));
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = get_short_name(i, i->val, '@', &(i->short_name));
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosevoid *ASN1_TYPE_unpack_sequence(const ASN1_ITEM *it, const ASN1_TYPE *t)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (t == NULL || t->type != V_ASN1_SEQUENCE || t->value.sequence == NULL)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosestatic int add_pkinit_princ_to_san_list(TALLOC_CTX *mem_ctx,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose const unsigned char *p;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose oct = current->d.otherName->value->value.sequence;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose princ = d2i_KRB5PrincipalName(NULL, &p, oct->length);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose || sk_ASN1_GENERALSTRING_num(princ->principal_name->name_string)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose c < sk_ASN1_GENERALSTRING_num(princ->principal_name->name_string);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (c > 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = get_short_name(i, i->val, '@', &(i->short_name));
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosestatic int add_ip_to_san_list(TALLOC_CTX *mem_ctx, enum san_opt san_opt,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i->val = talloc_strndup(i, (const char *) data, len);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosestatic int get_rdn_list(TALLOC_CTX *mem_ctx, X509_NAME *name,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose const char ***rdn_list)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose const char *sn;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose for (c = 0; c < X509_NAME_entry_count(name); c++) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = ASN1_STRING_print_ex(bio_mem, rdn_str, ASN1_STRFLGS_RFC2253);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose tmp_str_size = BIO_get_mem_data(bio_mem, &tmp_str);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose list[c] = talloc_asprintf(list, "%s=%.*s", openssl_2_nss_attr_name(sn),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose /* BIO_reset() for BIO_s_mem returns 1 for sucess */
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosestatic int add_rdn_list_to_san_list(TALLOC_CTX *mem_ctx,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosestatic int add_oid_to_san_list(TALLOC_CTX *mem_ctx,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose char oid_buf[128]; /* FIXME: any other size ?? */
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose len = OBJ_obj2txt(oid_buf, sizeof(oid_buf), oid, 1);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosestatic int get_san(TALLOC_CTX *mem_ctx, X509 *cert, struct san_list **san_list)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose unsigned char *data;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose unsigned char *p;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose extsan = X509_get_ext_d2i(cert, NID_subject_alt_name, &crit, NULL);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (crit == -1) { /* extension could not be found */
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose for (c = 0; c < sk_GENERAL_NAME_num(extsan); c++) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (strcmp(item_s->other_name_oid, NT_PRINCIPAL_OID) == 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = add_nt_princ_to_san_list(mem_ctx, SAN_NT, current,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose } else if (strcmp(item_s->other_name_oid, PKINIT_OID) == 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = add_pkinit_princ_to_san_list(mem_ctx, SAN_PKINIT,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = add_principal_to_san_list(mem_ctx, SAN_PRINCIPAL,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = get_short_name(item, item->val, '@', &(item->short_name));
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = get_short_name(item, item->val, '.', &(item->short_name));
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_STRING_get0_data(current->d.uniformResourceIdentifier),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_STRING_length(current->d.uniformResourceIdentifier),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose len = i2d_ASN1_TYPE(current->d.x400Address, NULL);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose /* i2d_TYPE increment the second argument so that it points to the end of
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose * the written data hence we cannot use i->bin_val directly. */
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose len = i2d_EDIPARTYNAME(current->d.ediPartyName, NULL);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose /* i2d_TYPE increment the second argument so that it points to the end of
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose * the written data hence we cannot use i->bin_val directly. */
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose len = i2d_EDIPARTYNAME(current->d.ediPartyName, &data);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosestatic int get_extended_key_usage_oids(TALLOC_CTX *mem_ctx,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose const char ***_oids)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose char oid_buf[128]; /* FIXME: any other size ?? */
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose extusage = X509_get_ext_d2i(cert, NID_ext_key_usage, NULL, NULL);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose oids_list = talloc_zero_array(mem_ctx, const char *,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose for (c = 0; c < sk_ASN1_OBJECT_num(extusage); c++) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose oids_list[c] = talloc_strndup(oids_list, oid_buf, len);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose const unsigned char *der;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose cont = talloc_zero(mem_ctx, struct sss_cert_content);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = get_rdn_list(cont, tmp_name, &cont->issuer_rdn_list);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = rdn_list_2_dn_str(cont, NULL, cont->issuer_rdn_list,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = get_rdn_list(cont, tmp_name, &cont->subject_rdn_list);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = rdn_list_2_dn_str(cont, NULL, cont->subject_rdn_list,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (!(X509_get_extension_flags(cert) & EXFLAG_KUSAGE)) {