in projects/linux/asn1/dice/x509_extension_builder_openssl_dice_tcbinfo.c [63:203]
int x509_extension_builder_openssl_dice_tcbinfo_build (const struct x509_extension_builder *builder,
struct x509_extension *extension)
{
const struct x509_extension_builder_openssl_dice_tcbinfo *dice =
(const struct x509_extension_builder_openssl_dice_tcbinfo*) builder;
DICE_TCBINFO *tcbinfo;
BIGNUM *svn;
DICE_FWID *fwid;
ASN1_OBJECT *fwid_oid;
int fwid_len;
int status;
uint8_t *tcb_der = NULL;
int tcb_der_len;
if ((dice == NULL) || (extension == NULL)) {
return DICE_TCBINFO_EXTENSION_INVALID_ARGUMENT;
}
if (dice->tcb == NULL) {
return DICE_TCBINFO_EXTENSION_INVALID_ARGUMENT;
}
if (dice->tcb->version == NULL) {
return DICE_TCBINFO_EXTENSION_NO_VERSION;
}
if ((dice->tcb->svn == NULL) || (dice->tcb->svn_length == 0)) {
return DICE_TCBINFO_EXTENSION_NO_SVN;
}
if (dice->tcb->fwid == NULL) {
return DICE_TCBINFO_EXTENSION_NO_FWID;
}
switch (dice->tcb->fwid_hash) {
case HASH_TYPE_SHA1:
fwid_len = SHA1_HASH_LENGTH;
fwid_oid = OBJ_nid2obj (EVP_MD_type (EVP_sha1 ()));
break;
case HASH_TYPE_SHA256:
fwid_len = SHA256_HASH_LENGTH;
fwid_oid = OBJ_nid2obj (EVP_MD_type (EVP_sha256 ()));
break;
case HASH_TYPE_SHA384:
fwid_len = SHA384_HASH_LENGTH;
fwid_oid = OBJ_nid2obj (EVP_MD_type (EVP_sha384 ()));
break;
case HASH_TYPE_SHA512:
fwid_len = SHA512_HASH_LENGTH;
fwid_oid = OBJ_nid2obj (EVP_MD_type (EVP_sha512 ()));
break;
default:
return DICE_TCBINFO_EXTENSION_UNKNOWN_FWID;
}
if (fwid_oid == NULL) {
return -ERR_get_error ();
}
tcbinfo = DICE_TCBINFO_new ();
if (tcbinfo == NULL) {
status = -ERR_get_error ();
goto err_tcb;
}
tcbinfo->version = ASN1_IA5STRING_new ();
if (tcbinfo->version == NULL) {
status = DICE_TCBINFO_EXTENSION_NO_MEMORY;
goto err_build;
}
tcbinfo->version->length = strlen (dice->tcb->version);
tcbinfo->version->data = (unsigned char*) strdup (dice->tcb->version);
if (tcbinfo->version->data == NULL) {
status = DICE_TCBINFO_EXTENSION_NO_MEMORY;
goto err_build;
}
svn = BN_bin2bn (dice->tcb->svn, dice->tcb->svn_length, NULL);
if (svn == NULL) {
status = DICE_TCBINFO_EXTENSION_NO_MEMORY;
goto err_build;
}
tcbinfo->svn = BN_to_ASN1_INTEGER (svn, NULL);
BN_free (svn);
if (tcbinfo->svn == NULL) {
status = DICE_TCBINFO_EXTENSION_NO_MEMORY;
goto err_build;
}
tcbinfo->digests = sk_DICE_FWID_new_null ();
if (tcbinfo->digests == NULL) {
status = DICE_TCBINFO_EXTENSION_NO_MEMORY;
goto err_build;
}
fwid = DICE_FWID_new ();
if (fwid == NULL) {
status = DICE_TCBINFO_EXTENSION_NO_MEMORY;
goto err_build;
}
ASN1_OBJECT_free (fwid->hash_alg);
fwid->hash_alg = fwid_oid;
if (ASN1_OCTET_STRING_set (fwid->digest, dice->tcb->fwid, fwid_len) == 0) {
status = -ERR_get_error ();
goto err_fwid;
}
status = sk_DICE_FWID_push (tcbinfo->digests, fwid);
if (status == 0) {
status = DICE_TCBINFO_EXTENSION_NO_MEMORY;
goto err_fwid;
}
tcb_der_len = i2d_DICE_TCBINFO (tcbinfo, &tcb_der);
if (tcb_der_len < 0) {
status = -ERR_get_error ();
goto err_build;
}
x509_extension_builder_init_extension_descriptor (extension, false,
X509_EXTENSION_BUILDER_DICE_TCBINFO_OID, X509_EXTENSION_BUILDER_DICE_TCBINFO_OID_LENGTH,
tcb_der, tcb_der_len);
DICE_TCBINFO_free (tcbinfo);
return 0;
err_fwid:
DICE_FWID_free (fwid);
err_build:
DICE_TCBINFO_free (tcbinfo);
err_tcb:
return status;
}