Skip to content

Commit

Permalink
Attribute certificate getter and setter API
Browse files Browse the repository at this point in the history
Only fields that are allowed by RFC 5755 are
accessible through this API.  Fields that are only supported
in version 1 attribute certificates (e.g. the AttCertIssuer
v1Form fields) are not implemented.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
(Merged from #15857)
  • Loading branch information
dhobsong authored and mattcaswell committed Apr 24, 2024
1 parent 7dcee34 commit 9e1a8b5
Show file tree
Hide file tree
Showing 13 changed files with 601 additions and 12 deletions.
2 changes: 1 addition & 1 deletion crypto/x509/build.info
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ SOURCE[../../libcrypto]=\
pcy_cache.c pcy_node.c pcy_data.c pcy_map.c pcy_tree.c pcy_lib.c \
v3_asid.c v3_addr.c v3_tlsf.c v3_admis.c v3_no_rev_avail.c \
v3_soa_id.c v3_no_ass.c v3_group_ac.c v3_single_use.c v3_ind_iss.c \
x509_acert.c
x509_acert.c x509aset.c

IF[{- !$disabled{'deprecated-3.0'} -}]
SOURCE[../../libcrypto]=x509type.c
Expand Down
110 changes: 110 additions & 0 deletions crypto/x509/x509_acert.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,113 @@ IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X509_ACERT_ISSUER_V2FORM)

IMPLEMENT_PEM_rw(X509_ACERT, X509_ACERT, PEM_STRING_ACERT, X509_ACERT)

static X509_NAME *get_dirName(const GENERAL_NAMES *names)
{
GENERAL_NAME *dirName;

if (sk_GENERAL_NAME_num(names) != 1)
return NULL;

dirName = sk_GENERAL_NAME_value(names, 0);
if (dirName->type != GEN_DIRNAME)
return NULL;

return dirName->d.directoryName;
}

void OSSL_OBJECT_DIGEST_INFO_get0_digest(const OSSL_OBJECT_DIGEST_INFO *o,
int *digestedObjectType,
const X509_ALGOR **digestAlgorithm,
const ASN1_BIT_STRING **digest)
{
if (digestedObjectType != NULL)
*digestedObjectType = ASN1_ENUMERATED_get(&o->digestedObjectType);
if (digestAlgorithm != NULL)
*digestAlgorithm = &o->digestAlgorithm;
if (digest != NULL)
*digest = &o->objectDigest;
}

const X509_NAME *OSSL_ISSUER_SERIAL_get0_issuer(const OSSL_ISSUER_SERIAL *isss)
{
return get_dirName(isss->issuer);
}

const ASN1_INTEGER *OSSL_ISSUER_SERIAL_get0_serial(const OSSL_ISSUER_SERIAL *isss)
{
return &isss->serial;
}

const ASN1_BIT_STRING *OSSL_ISSUER_SERIAL_get0_issuerUID(const OSSL_ISSUER_SERIAL *isss)
{
return isss->issuerUID;
}

long X509_ACERT_get_version(const X509_ACERT *x)
{
return ASN1_INTEGER_get(&x->acinfo->version);
}

void X509_ACERT_get0_signature(const X509_ACERT *x,
const ASN1_BIT_STRING **psig,
const X509_ALGOR **palg)
{
if (psig != NULL)
*psig = &x->signature;
if (palg != NULL)
*palg = &x->sig_alg;
}

int X509_ACERT_get_signature_nid(const X509_ACERT *x)
{
return OBJ_obj2nid(x->sig_alg.algorithm);
}

const GENERAL_NAMES *X509_ACERT_get0_holder_entityName(const X509_ACERT *x)
{
return x->acinfo->holder.entityName;
}

const OSSL_ISSUER_SERIAL *X509_ACERT_get0_holder_baseCertId(const X509_ACERT *x)
{
return x->acinfo->holder.baseCertificateID;
}

const OSSL_OBJECT_DIGEST_INFO *X509_ACERT_get0_holder_digest(const X509_ACERT *x)
{
return x->acinfo->holder.objectDigestInfo;
}

const X509_NAME *X509_ACERT_get0_issuerName(const X509_ACERT *x)
{
if (x->acinfo->issuer.type != X509_ACERT_ISSUER_V2
|| x->acinfo->issuer.u.v2Form == NULL)
return NULL;

return get_dirName(x->acinfo->issuer.u.v2Form->issuerName);
}

const ASN1_BIT_STRING *X509_ACERT_get0_issuerUID(const X509_ACERT *x)
{
return x->acinfo->issuerUID;
}

const X509_ALGOR *X509_ACERT_get0_info_sigalg(const X509_ACERT *x)
{
return &x->acinfo->signature;
}

const ASN1_INTEGER *X509_ACERT_get0_serialNumber(const X509_ACERT *x)
{
return &x->acinfo->serialNumber;
}

const ASN1_GENERALIZEDTIME *X509_ACERT_get0_notBefore(const X509_ACERT *x)
{
return x->acinfo->validityPeriod.notBefore;
}

const ASN1_GENERALIZEDTIME *X509_ACERT_get0_notAfter(const X509_ACERT *x)
{
return x->acinfo->validityPeriod.notAfter;
}
177 changes: 177 additions & 0 deletions crypto/x509/x509aset.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
/*
* Copyright 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 <openssl/err.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "x509_acert.h"

static int replace_gentime(ASN1_STRING **dest, const ASN1_GENERALIZEDTIME *src)
{
ASN1_STRING *s;

if (src->type != V_ASN1_GENERALIZEDTIME)
return 0;

if (*dest == src)
return 1;

s = ASN1_STRING_dup(src);
if (s == NULL) {
ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB);
return 0;
}

ASN1_STRING_free(*dest);
*dest = s;

return 1;
}

static int replace_dirName(GENERAL_NAMES **names, const X509_NAME *dirName)
{
GENERAL_NAME *gen_name = NULL;
STACK_OF(GENERAL_NAME) *new_names = NULL;
X509_NAME *name_copy;

if ((name_copy = X509_NAME_dup(dirName)) == NULL) {
ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB);
goto err;
}

if ((new_names = sk_GENERAL_NAME_new_null()) == NULL) {
ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB);
goto err;
}

if ((gen_name = GENERAL_NAME_new()) == NULL) {
ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB);
goto err;
}

if (sk_GENERAL_NAME_push(new_names, gen_name) <= 0) {
ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB);
goto err;
}

GENERAL_NAME_set0_value(gen_name, GEN_DIRNAME, name_copy);

GENERAL_NAMES_free(*names);
*names = new_names;

return 1;

err:
GENERAL_NAME_free(gen_name);
sk_GENERAL_NAME_free(new_names);
X509_NAME_free(name_copy);
return 0;
}

int OSSL_OBJECT_DIGEST_INFO_set1_digest(OSSL_OBJECT_DIGEST_INFO *o,
int digestedObjectType,
X509_ALGOR *digestAlgorithm,
ASN1_BIT_STRING *digest)
{

if (ASN1_ENUMERATED_set(&o->digestedObjectType, digestedObjectType) <= 0)
return 0;

if (X509_ALGOR_copy(&o->digestAlgorithm, digestAlgorithm) <= 0)
return 0;

if (ASN1_STRING_copy(&o->objectDigest, digest) <= 0)
return 0;

return 1;
}

int OSSL_ISSUER_SERIAL_set1_issuer(OSSL_ISSUER_SERIAL *isss,
const X509_NAME *issuer)
{
return replace_dirName(&isss->issuer, issuer);
}

int OSSL_ISSUER_SERIAL_set1_serial(OSSL_ISSUER_SERIAL *isss,
const ASN1_INTEGER *serial)
{
return ASN1_STRING_copy(&isss->serial, serial);
}

int OSSL_ISSUER_SERIAL_set1_issuerUID(OSSL_ISSUER_SERIAL *isss,
const ASN1_BIT_STRING *uid)
{
ASN1_BIT_STRING_free(isss->issuerUID);
isss->issuerUID = ASN1_STRING_dup(uid);
if (isss->issuerUID == NULL) {
ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB);
return 0;
}
return 1;
}

int X509_ACERT_set_version(X509_ACERT *x, long version)
{
return ASN1_INTEGER_set(&x->acinfo->version, version);
}

void X509_ACERT_set0_holder_entityName(X509_ACERT *x, GENERAL_NAMES *names)
{
GENERAL_NAMES_free(x->acinfo->holder.entityName);
x->acinfo->holder.entityName = names;
}

void X509_ACERT_set0_holder_baseCertId(X509_ACERT *x,
OSSL_ISSUER_SERIAL *isss)
{
OSSL_ISSUER_SERIAL_free(x->acinfo->holder.baseCertificateID);
x->acinfo->holder.baseCertificateID = isss;
}

void X509_ACERT_set0_holder_digest(X509_ACERT *x,
OSSL_OBJECT_DIGEST_INFO *dinfo)
{
OSSL_OBJECT_DIGEST_INFO_free(x->acinfo->holder.objectDigestInfo);
x->acinfo->holder.objectDigestInfo = dinfo;
}

int X509_ACERT_set1_issuerName(X509_ACERT *x, const X509_NAME *name)
{
X509_ACERT_ISSUER_V2FORM *v2Form;

v2Form = x->acinfo->issuer.u.v2Form;

/* only v2Form is supported, so always create that version */
if (v2Form == NULL) {
v2Form = X509_ACERT_ISSUER_V2FORM_new();
if (v2Form == NULL) {
ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB);
return 0;
}
x->acinfo->issuer.u.v2Form = v2Form;
x->acinfo->issuer.type = X509_ACERT_ISSUER_V2;
}

return replace_dirName(&v2Form->issuerName, name);
}

int X509_ACERT_set1_serialNumber(X509_ACERT *x, const ASN1_INTEGER *serial)
{
return ASN1_STRING_copy(&x->acinfo->serialNumber, serial);
}

int X509_ACERT_set1_notBefore(X509_ACERT *x, const ASN1_GENERALIZEDTIME *time)
{
return replace_gentime(&x->acinfo->validityPeriod.notBefore, time);
}

int X509_ACERT_set1_notAfter(X509_ACERT *x, const ASN1_GENERALIZEDTIME *time)
{
return replace_gentime(&x->acinfo->validityPeriod.notAfter, time);
}
6 changes: 6 additions & 0 deletions doc/build.info
Original file line number Diff line number Diff line change
Expand Up @@ -2799,6 +2799,10 @@ DEPEND[html/man3/X509V3_set_ctx.html]=man3/X509V3_set_ctx.pod
GENERATE[html/man3/X509V3_set_ctx.html]=man3/X509V3_set_ctx.pod
DEPEND[man/man3/X509V3_set_ctx.3]=man3/X509V3_set_ctx.pod
GENERATE[man/man3/X509V3_set_ctx.3]=man3/X509V3_set_ctx.pod
DEPEND[html/man3/X509_ACERT_get0_holder_baseCertId.html]=man3/X509_ACERT_get0_holder_baseCertId.pod
GENERATE[html/man3/X509_ACERT_get0_holder_baseCertId.html]=man3/X509_ACERT_get0_holder_baseCertId.pod
DEPEND[man/man3/X509_ACERT_get0_holder_baseCertId.3]=man3/X509_ACERT_get0_holder_baseCertId.pod
GENERATE[man/man3/X509_ACERT_get0_holder_baseCertId.3]=man3/X509_ACERT_get0_holder_baseCertId.pod
DEPEND[html/man3/X509_ALGOR_dup.html]=man3/X509_ALGOR_dup.pod
GENERATE[html/man3/X509_ALGOR_dup.html]=man3/X509_ALGOR_dup.pod
DEPEND[man/man3/X509_ALGOR_dup.3]=man3/X509_ALGOR_dup.pod
Expand Down Expand Up @@ -3631,6 +3635,7 @@ html/man3/UI_create_method.html \
html/man3/UI_new.html \
html/man3/X509V3_get_d2i.html \
html/man3/X509V3_set_ctx.html \
html/man3/X509_ACERT_get0_holder_baseCertId.html \
html/man3/X509_ALGOR_dup.html \
html/man3/X509_ATTRIBUTE.html \
html/man3/X509_CRL_get0_by_serial.html \
Expand Down Expand Up @@ -4276,6 +4281,7 @@ man/man3/UI_create_method.3 \
man/man3/UI_new.3 \
man/man3/X509V3_get_d2i.3 \
man/man3/X509V3_set_ctx.3 \
man/man3/X509_ACERT_get0_holder_baseCertId.3 \
man/man3/X509_ALGOR_dup.3 \
man/man3/X509_ATTRIBUTE.3 \
man/man3/X509_CRL_get0_by_serial.3 \
Expand Down

0 comments on commit 9e1a8b5

Please sign in to comment.