Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crypto/x509/build.info
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ SOURCE[../../libcrypto]=\
v3_no_rev_avail.c v3_soa_id.c v3_no_ass.c v3_group_ac.c \
v3_single_use.c v3_ac_tgt.c v3_audit_id.c v3_bacons.c v3_sda.c \
v3_usernotice.c x_unotice.c x_iserial.c v3_authattid.c v3_iobo.c \
v3_aaa.c v3_attrmap.c v3_ind_iss.c
v3_aaa.c v3_attrmap.c v3_ind_iss.c v3_attrdesc.c

IF[{- !$disabled{'deprecated-3.0'} -}]
SOURCE[../../libcrypto]=x509type.c
Expand Down
1 change: 1 addition & 0 deletions crypto/x509/ext_dat.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,4 @@ extern const X509V3_EXT_METHOD ossl_v3_allowed_attribute_assignments;
extern const X509V3_EXT_METHOD ossl_v3_attribute_mappings;
extern const X509V3_EXT_METHOD ossl_v3_holder_name_constraints;
extern const X509V3_EXT_METHOD ossl_v3_indirect_issuer;
extern const X509V3_EXT_METHOD ossl_v3_attribute_descriptor;
2 changes: 1 addition & 1 deletion crypto/x509/standard_exts.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ static const X509V3_EXT_METHOD *standard_exts[] = {
&ossl_v3_bacons,
&ossl_v3_delegated_name_constraints,
// TODO: timeSpecification
// TODO: attributeDescriptor
&ossl_v3_attribute_descriptor,
&ossl_v3_user_notice,
&ossl_v3_soa_identifier,
&ossl_v3_acc_cert_policies,
Expand Down
189 changes: 189 additions & 0 deletions crypto/x509/v3_attrdesc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
/*
* Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/

#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/conf.h>
#include <openssl/x509v3.h>
#include "ext_dat.h"
#include "x509_local.h"

ASN1_SEQUENCE(HASH) = {
ASN1_SIMPLE(HASH, algorithmIdentifier, X509_ALGOR),
ASN1_OPT(HASH, hashValue, ASN1_BIT_STRING),
} ASN1_SEQUENCE_END(HASH)

ASN1_SEQUENCE(INFO_SYNTAX_POINTER) = {
ASN1_SIMPLE(INFO_SYNTAX_POINTER, name, GENERAL_NAMES),
ASN1_OPT(INFO_SYNTAX_POINTER, hash, HASH),
} ASN1_SEQUENCE_END(INFO_SYNTAX_POINTER)

ASN1_CHOICE(INFO_SYNTAX) = {
ASN1_SIMPLE(INFO_SYNTAX, choice.content, DIRECTORYSTRING),
ASN1_SIMPLE(INFO_SYNTAX, choice.pointer, INFO_SYNTAX_POINTER)
} ASN1_CHOICE_END(INFO_SYNTAX)

ASN1_SEQUENCE(PRIVILEGE_POLICY_ID) = {
ASN1_SIMPLE(PRIVILEGE_POLICY_ID, privilegePolicy, ASN1_OBJECT),
ASN1_SIMPLE(PRIVILEGE_POLICY_ID, privPolSyntax, INFO_SYNTAX),
} ASN1_SEQUENCE_END(PRIVILEGE_POLICY_ID)

ASN1_SEQUENCE(ATTRIBUTE_DESCRIPTOR) = {
ASN1_SIMPLE(ATTRIBUTE_DESCRIPTOR, identifier, ASN1_OBJECT),
ASN1_SIMPLE(ATTRIBUTE_DESCRIPTOR, attributeSyntax, ASN1_OCTET_STRING),
ASN1_IMP_OPT(ATTRIBUTE_DESCRIPTOR, name, ASN1_UTF8STRING, 0),
ASN1_IMP_OPT(ATTRIBUTE_DESCRIPTOR, description, ASN1_UTF8STRING, 1),
ASN1_SIMPLE(ATTRIBUTE_DESCRIPTOR, dominationRule, PRIVILEGE_POLICY_ID),
} ASN1_SEQUENCE_END(ATTRIBUTE_DESCRIPTOR)

IMPLEMENT_ASN1_FUNCTIONS(ATTRIBUTE_DESCRIPTOR)

// static STACK_OF(CONF_VALUE) *i2v_BASIC_ATTR_CONSTRAINTS(X509V3_EXT_METHOD *method,
// BASIC_ATTR_CONSTRAINTS *bcons,
// STACK_OF(CONF_VALUE)
// *extlist)
// {
// X509V3_add_value_bool("authority", bcons->authority, &extlist);
// X509V3_add_value_int("pathlen", bcons->pathlen, &extlist);
// return extlist;
// }

// static BASIC_ATTR_CONSTRAINTS *v2i_BASIC_ATTR_CONSTRAINTS(X509V3_EXT_METHOD *method,
// X509V3_CTX *ctx,
// STACK_OF(CONF_VALUE) *values)
// {
// BASIC_ATTR_CONSTRAINTS *bcons = NULL;
// CONF_VALUE *val;
// int i;

// if ((bcons = BASIC_ATTR_CONSTRAINTS_new()) == NULL) {
// ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB);
// return NULL;
// }
// for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
// val = sk_CONF_VALUE_value(values, i);
// if (strcmp(val->name, "authority") == 0) {
// if (!X509V3_get_value_bool(val, &bcons->authority))
// goto err;
// } else if (strcmp(val->name, "pathlen") == 0) {
// if (!X509V3_get_value_int(val, &bcons->pathlen))
// goto err;
// } else {
// ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_NAME);
// X509V3_conf_add_error_name_value(val);
// goto err;
// }
// }
// return bcons;
// err:
// BASIC_ATTR_CONSTRAINTS_free(bcons);
// return NULL;
// }

static int i2r_HASH(X509V3_EXT_METHOD *method,
HASH *hash,
BIO *out, int indent)
{
BIO_printf(out, "%*sAlgorithm: ", indent, "");
i2a_ASN1_OBJECT(out, hash->algorithmIdentifier->algorithm);
BIO_puts(out, "\n");
if (hash->algorithmIdentifier->parameter) {
BIO_printf(out, "%*sParameter: ", indent, "");
print_attribute_value(out, 0, hash->algorithmIdentifier->parameter);
BIO_puts(out, "\n");
}
BIO_printf(out, "%*sHash Value: ", indent, "");
print_hex(out, hash->hashValue->data, hash->hashValue->length);
return 1;
}

static int i2r_INFO_SYNTAX_POINTER(X509V3_EXT_METHOD *method,
INFO_SYNTAX_POINTER *pointer,
BIO *out, int indent)
{
BIO_printf(out, "%*sNames:\n", indent, "");
ossl_print_gens(out, pointer->name, indent + 4);
BIO_puts(out, "\n");
if (pointer->hash != NULL) {
BIO_printf(out, "%*sHash:\n", indent, "");
i2r_HASH(method, pointer->hash, out, indent + 4);
}
return 1;
}

static int i2r_INFO_SYNTAX(X509V3_EXT_METHOD *method,
INFO_SYNTAX *info,
BIO *out, int indent)
{
switch (info->type) {
case (INFO_SYNTAX_TYPE_CONTENT): {
BIO_printf(out, "%*sContent: ", indent, "");
BIO_printf(out, "%.*s", info->choice.content->length, info->choice.content->data);
BIO_puts(out, "\n");
return 1;
}
case (INFO_SYNTAX_TYPE_POINTER): {
BIO_printf(out, "%*sPointer:\n", indent, "");
return i2r_INFO_SYNTAX_POINTER(method, info->choice.pointer, out, indent + 4);
}
default: return 0;
}
return 0;
}

static int i2r_PRIVILEGE_POLICY_ID(X509V3_EXT_METHOD *method,
PRIVILEGE_POLICY_ID *ppid,
BIO *out, int indent)
{
BIO_printf(out, "%*sIdentifier: ", indent, "");
i2a_ASN1_OBJECT(out, ppid->privilegePolicy);
BIO_puts(out, "\n");
BIO_printf(out, "%*sSyntax:\n", indent, "");
i2r_INFO_SYNTAX(method, ppid->privPolSyntax, out, indent + 4);
return 1;
}

static int i2r_ATTRIBUTE_DESCRIPTOR(X509V3_EXT_METHOD *method,
ATTRIBUTE_DESCRIPTOR *ad,
BIO *out, int indent)
{
BIO_printf(out, "%*sIdentifier: ", indent, "");
i2a_ASN1_OBJECT(out, ad->identifier);
BIO_puts(out, "\n");
BIO_printf(out, "%*sSyntax: ", indent, "");
BIO_printf(out, "%.*s", ad->attributeSyntax->length, ad->attributeSyntax->data);
BIO_puts(out, "\n");
if (ad->name != NULL) {
BIO_printf(out, "%*sName: ", indent, "");
BIO_printf(out, "%.*s", ad->name->length, ad->name->data);
BIO_puts(out, "\n");
}
if (ad->description != NULL) {
BIO_printf(out, "%*sDescription: ", indent, "");
BIO_printf(out, "%.*s", ad->description->length, ad->description->data);
BIO_puts(out, "\n");
}
BIO_printf(out, "%*sDomination Rule:\n", indent, "");
i2r_PRIVILEGE_POLICY_ID(method, ad->dominationRule, out, indent + 4);
return 1;
}

const X509V3_EXT_METHOD ossl_v3_attribute_descriptor = {
NID_attribute_descriptor, 0,
ASN1_ITEM_ref(ATTRIBUTE_DESCRIPTOR),
0, 0, 0, 0,
0, 0,
0, // (X509V3_EXT_I2V)i2v_BASIC_ATTR_CONSTRAINTS,
0, // (X509V3_EXT_V2I)v2i_BASIC_ATTR_CONSTRAINTS,
(X509V3_EXT_I2R)i2r_ATTRIBUTE_DESCRIPTOR,
NULL,
NULL
};
40 changes: 40 additions & 0 deletions include/openssl/x509v3.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -1157,6 +1157,46 @@ DECLARE_ASN1_FUNCTIONS(ATTRIBUTE_MAPPINGS)
generate_stack_macros("ATTRIBUTE_MAPPING");
-}

typedef struct HASH_st {
X509_ALGOR *algorithmIdentifier;
ASN1_BIT_STRING *hashValue;
} HASH;

typedef struct INFO_SYNTAX_POINTER_st {
GENERAL_NAMES *name;
HASH *hash;
} INFO_SYNTAX_POINTER;

#define INFO_SYNTAX_TYPE_CONTENT 0;
#define INFO_SYNTAX_TYPE_POINTER 1;

typedef struct INFO_SYNTAX_st {
int type;
union {
ASN1_STRING *content;
INFO_SYNTAX_POINTER *pointer;
} choice;
} INFO_SYNTAX;

typedef struct PRIVILEGE_POLICY_ID_st {
ASN1_OBJECT *privilegePolicy;
INFO_SYNTAX *privPolSyntax;
} PRIVILEGE_POLICY_ID;

typedef struct ATTRIBUTE_DESCRIPTOR_st {
ASN1_OBJECT *identifier;
ASN1_STRING *attributeSyntax;
ASN1_UTF8STRING *name;
ASN1_UTF8STRING *description;
PRIVILEGE_POLICY_ID *dominationRule;
} ATTRIBUTE_DESCRIPTOR;

DECLARE_ASN1_FUNCTIONS(HASH)
DECLARE_ASN1_FUNCTIONS(INFO_SYNTAX_POINTER)
DECLARE_ASN1_FUNCTIONS(INFO_SYNTAX)
DECLARE_ASN1_FUNCTIONS(PRIVILEGE_POLICY_ID)
DECLARE_ASN1_FUNCTIONS(ATTRIBUTE_DESCRIPTOR)

# ifdef __cplusplus
}
# endif
Expand Down
13 changes: 13 additions & 0 deletions test/certs/ext-attributeDescriptor.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-----BEGIN CERTIFICATE-----
MIICCzCCAfegAwIBAgIDAQIDMAsGCSqGSIb3DQEBBTAAMCIYDzIwMjEwODMxMDEw
NzA5WhgPMjAyMTA4MzEwMTA3MDlaMAAwggEgMAsGCSqGSIb3DQEBAQOCAQ8AMIIB
CgKCAQEAtnjLm1ts1hC4fNNt3UnQD9y73bDXgioTyWYSI3ca/KNfuTydjFTEYAmq
nuGrBOUfgbmH3PRQ0AmpqljgWTb3d3K8H4UFvDWQTPSS21IMjm8oqd19nE5GxWir
Gu0oDRzhWLHe1RZ7ZrohCPg/1Ocsy47QZuK2laFB0rEmrRWBmEYbDl3/wxf5XfqI
qpOynJB02thXrTCcTM7Rz1FqCFt/ZVZB5hKY2S+CTdE9OIVKlr4WHMfuvUYeOj06
GkwLFJHNv2tU+tovI3mYRxUuY4UupkS3MC+Otey7XKm1P+INjWWoegm6iCAt3Vus
pVz+6pU2xgl3nrAVMQHB4fReQPH0pQIDAQABo4GRMIGOMIGLBgNVHTAEgYMwgYAG
A1UEAwQYVW5ib3VuZGVkRGlyZWN0b3J5U3RyaW5ngApjb21tb25OYW1lgRZBIGdl
bmVyYWwtcHVycG9zZSBuYW1lMDsGA1UECjA0MCCkHjAcMRowGAYDVQQDDBFXaWxk
Ym9hciBTb2Z0d2FyZTAQMAsGCWCGSAFlAwQCAQMBADALBgkqhkiG9w0BAQUDAQA=
-----END CERTIFICATE-----
25 changes: 25 additions & 0 deletions util/libcrypto.num
Original file line number Diff line number Diff line change
Expand Up @@ -5650,3 +5650,28 @@ i2d_ATTRIBUTE_MAPPINGS ? 3_2_0 EXIST::FUNCTION:
ATTRIBUTE_MAPPINGS_free ? 3_2_0 EXIST::FUNCTION:
ATTRIBUTE_MAPPINGS_new ? 3_2_0 EXIST::FUNCTION:
ATTRIBUTE_MAPPINGS_it ? 3_2_0 EXIST::FUNCTION:
d2i_HASH ? 3_2_0 EXIST::FUNCTION:
i2d_HASH ? 3_2_0 EXIST::FUNCTION:
HASH_free ? 3_2_0 EXIST::FUNCTION:
HASH_new ? 3_2_0 EXIST::FUNCTION:
HASH_it ? 3_2_0 EXIST::FUNCTION:
d2i_INFO_SYNTAX_POINTER ? 3_2_0 EXIST::FUNCTION:
i2d_INFO_SYNTAX_POINTER ? 3_2_0 EXIST::FUNCTION:
INFO_SYNTAX_POINTER_free ? 3_2_0 EXIST::FUNCTION:
INFO_SYNTAX_POINTER_new ? 3_2_0 EXIST::FUNCTION:
INFO_SYNTAX_POINTER_it ? 3_2_0 EXIST::FUNCTION:
d2i_INFO_SYNTAX ? 3_2_0 EXIST::FUNCTION:
i2d_INFO_SYNTAX ? 3_2_0 EXIST::FUNCTION:
INFO_SYNTAX_free ? 3_2_0 EXIST::FUNCTION:
INFO_SYNTAX_new ? 3_2_0 EXIST::FUNCTION:
INFO_SYNTAX_it ? 3_2_0 EXIST::FUNCTION:
d2i_PRIVILEGE_POLICY_ID ? 3_2_0 EXIST::FUNCTION:
i2d_PRIVILEGE_POLICY_ID ? 3_2_0 EXIST::FUNCTION:
PRIVILEGE_POLICY_ID_free ? 3_2_0 EXIST::FUNCTION:
PRIVILEGE_POLICY_ID_new ? 3_2_0 EXIST::FUNCTION:
PRIVILEGE_POLICY_ID_it ? 3_2_0 EXIST::FUNCTION:
d2i_ATTRIBUTE_DESCRIPTOR ? 3_2_0 EXIST::FUNCTION:
i2d_ATTRIBUTE_DESCRIPTOR ? 3_2_0 EXIST::FUNCTION:
ATTRIBUTE_DESCRIPTOR_free ? 3_2_0 EXIST::FUNCTION:
ATTRIBUTE_DESCRIPTOR_new ? 3_2_0 EXIST::FUNCTION:
ATTRIBUTE_DESCRIPTOR_it ? 3_2_0 EXIST::FUNCTION: