Skip to content

Commit

Permalink
Code refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
aveenismail committed Nov 27, 2023
1 parent 8b59c66 commit 9add8cc
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 127 deletions.
80 changes: 52 additions & 28 deletions lib/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -1387,25 +1387,55 @@ uint32_t ykpiv_util_slot_object(uint8_t slot) {
}

ykpiv_rc ykpiv_util_get_certdata(uint8_t *buf, size_t buf_len, uint8_t* certdata, unsigned long *certdata_len) {
size_t offs, len = 0;
uint8_t compress_info = 0;
uint8_t *certptr;
size_t cert_len = 0;
uint8_t *ptr = buf;
unsigned long ul_buflen = (unsigned long)buf_len;

ptr++;
offs = _ykpiv_get_length(ptr, buf + ul_buflen, &len);
if(!offs) {
*certdata_len = 0;
return YKPIV_OK;
while (ptr < buf + buf_len) {
switch (*ptr) {
case TAG_CERT:
ptr++; // move to after tag byte
size_t offs = _ykpiv_get_length(ptr, buf + (unsigned long) buf_len, &cert_len);
if(!offs) {
*certdata_len = 0;
return YKPIV_OK;
}
ptr += offs; // move to after length bytes
certptr = ptr;
ptr += cert_len; // move to after cert bytes
break;
case TAG_CERT_COMPRESS:
ptr++; // move to after tag byte
ptr++; // move to after length byte
compress_info = *ptr++;
break;
case TAG_CERT_LRC:
// Basically, skip over it
ptr++; // move after tag bytes
size_t lrc_len = *ptr++; // move to after length byte
ptr += lrc_len; // move to after value bytes
break;
default:
fprintf(stderr, "Unknown cert tag. Treating this as a raw certificate\n");
if (*certdata_len < buf_len) {
fprintf(stderr, "Buffer too small\n");
*certdata_len = 0;
return YKPIV_SIZE_ERROR;
}
memmove(certdata, buf, buf_len);
*certdata_len = buf_len;
return YKPIV_OK;
}
}
ptr += offs;

if (buf[buf_len - 3] == YKPIV_CERTINFO_GZIP) { // This byte is set to 1 if certinfo is YKPIV_CERTINFO_GZIP
if (compress_info == YKPIV_CERTINFO_GZIP) { // This byte is set to 1 if certinfo is YKPIV_CERTINFO_GZIP
z_stream zs;
zs.zalloc = Z_NULL;
zs.zfree = Z_NULL;
zs.opaque = Z_NULL;
zs.avail_in = (uInt) len;
zs.next_in = (Bytef *) ptr;
zs.avail_in = (uInt) cert_len;
zs.next_in = (Bytef *) certptr;
zs.avail_out = (uInt) *certdata_len;
zs.next_out = (Bytef *) certdata;

Expand All @@ -1426,8 +1456,8 @@ uint32_t ykpiv_util_slot_object(uint8_t slot) {
}
*certdata_len = zs.total_out;
} else {
memmove(certdata, ptr, len);
*certdata_len = len;
memmove(certdata, certptr, cert_len);
*certdata_len = cert_len;
}
return YKPIV_OK;
}
Expand All @@ -1438,7 +1468,7 @@ void ykpiv_util_write_certdata(uint8_t *rawdata, size_t rawdata_len, uint8_t cer
unsigned long len_bytes = get_length_size(rawdata_len);
memmove(certdata + len_bytes + 1, rawdata, rawdata_len);

certdata[offset] = TAG_CERT;
certdata[offset++] = TAG_CERT;
offset += _ykpiv_set_length(certdata+offset, rawdata_len);
offset += rawdata_len;
certdata[offset++] = TAG_CERT_COMPRESS;
Expand All @@ -1451,30 +1481,24 @@ void ykpiv_util_write_certdata(uint8_t *rawdata, size_t rawdata_len, uint8_t cer

static ykpiv_rc _read_certificate(ykpiv_state *state, uint8_t slot, uint8_t *buf, size_t *buf_len) {
ykpiv_rc res = YKPIV_OK;
unsigned long ul_len = (unsigned long)*buf_len;
int object_id = (int)ykpiv_util_slot_object(slot);

if (-1 == object_id) return YKPIV_INVALID_OBJECT;

if (YKPIV_OK == (res = _ykpiv_fetch_object(state, object_id, buf, &ul_len))) {
unsigned char data[YKPIV_OBJ_MAX_SIZE * 10] = {0};
unsigned long data_len = sizeof (data);

if (YKPIV_OK == (res = _ykpiv_fetch_object(state, object_id, data, &data_len))) {

// check that object contents are at least large enough to read the tag
if (ul_len < CB_OBJ_TAG_MIN) {
if (data_len < CB_OBJ_TAG_MIN) {
*buf_len = 0;
return YKPIV_OK;
}

// check that first byte indicates "certificate" type

if (buf[0] == TAG_CERT) {
unsigned char certdata[YKPIV_OBJ_MAX_SIZE * 10] = {0};
unsigned long certdata_len = sizeof (certdata);
if ((res = ykpiv_util_get_certdata(buf, ul_len, certdata, &certdata_len)) != YKPIV_OK) {
DBG("Failed to get certificate data");
return res;
}
memmove(buf, certdata, certdata_len);
*buf_len = certdata_len;
if ((res = ykpiv_util_get_certdata(data, data_len, buf, buf_len)) != YKPIV_OK) {
DBG("Failed to get certificate data");
return res;
}
} else {
*buf_len = 0;
Expand Down
162 changes: 80 additions & 82 deletions tool/yubico-piv-tool.c
Original file line number Diff line number Diff line change
Expand Up @@ -1547,7 +1547,6 @@ static void print_cert_info(ykpiv_state *state, enum enum_slot slot, const EVP_M
int object = (int)ykpiv_util_slot_object(get_slot_hex(slot));
int slot_name;
unsigned char data[YKPIV_OBJ_MAX_SIZE] = {0};
const unsigned char *ptr = data;
unsigned long len = sizeof(data);
X509 *x509 = NULL;
X509_NAME *subj;
Expand All @@ -1561,95 +1560,94 @@ static void print_cert_info(ykpiv_state *state, enum enum_slot slot, const EVP_M

fprintf(output, "Slot %x:\t", slot_name);

if(*ptr++ == TAG_CERT) {
unsigned int md_len = sizeof(data);
const ASN1_TIME *not_before, *not_after;
unsigned char certdata[YKPIV_OBJ_MAX_SIZE * 10] = {0};
unsigned long certdata_len = sizeof(certdata);
if(ykpiv_util_get_certdata(data, len, certdata, &certdata_len) != YKPIV_OK) {
fprintf(stderr, "Failed to get certificate data\n");
return;
}

unsigned char certdata[YKPIV_OBJ_MAX_SIZE * 10] = {0};
unsigned long certdata_len = sizeof (certdata);
if(ykpiv_util_get_certdata(data, len, certdata, &certdata_len) != YKPIV_OK) {
fprintf(stderr, "Failed to get certificate data\n");
return;
}
const unsigned char *certdata_ptr = certdata;
x509 = d2i_X509(NULL, &certdata_ptr, certdata_len);
const unsigned char *certdata_ptr = certdata;
x509 = d2i_X509(NULL, &certdata_ptr, certdata_len);
if (x509 == NULL) {
fprintf(output, "Parse error.\n");
return;
}

{
EVP_PKEY *key = X509_get_pubkey(x509);
if(!key) {
fprintf(output, "Parse error.\n");
goto cert_out;
}
fprintf(output, "\n\tAlgorithm:\t");
switch(get_algorithm(key)) {
case YKPIV_ALGO_RSA1024:
fprintf(output, "RSA1024\n");
break;
case YKPIV_ALGO_RSA2048:
fprintf(output, "RSA2048\n");
break;
case YKPIV_ALGO_ECCP256:
fprintf(output, "ECCP256\n");
break;
case YKPIV_ALGO_ECCP384:
fprintf(output, "ECCP384\n");
break;
default:
fprintf(output, "Unknown\n");
}
EVP_PKEY_free(key);
}
subj = X509_get_subject_name(x509);
if(!subj) {
fprintf(output, "Parse error.\n");
goto cert_out;
}
fprintf(output, "\tSubject DN:\t");
if(X509_NAME_print_ex_fp(output, subj, 0, XN_FLAG_COMPAT) != 1) {
fprintf(output, "Failed to write Subject DN.\n");
unsigned int md_len = sizeof(data);
const ASN1_TIME *not_before, *not_after;

EVP_PKEY *key = X509_get_pubkey(x509);
if(!key) {
fprintf(output, "Parse error.\n");
goto cert_out;
}
fprintf(output, "\n\tAlgorithm:\t");
switch(get_algorithm(key)) {
case YKPIV_ALGO_RSA1024:
fprintf(output, "RSA1024\n");
break;
case YKPIV_ALGO_RSA2048:
fprintf(output, "RSA2048\n");
break;
case YKPIV_ALGO_ECCP256:
fprintf(output, "ECCP256\n");
break;
case YKPIV_ALGO_ECCP384:
fprintf(output, "ECCP384\n");
break;
default:
fprintf(output, "Unknown\n");
}
EVP_PKEY_free(key);

subj = X509_get_subject_name(x509);
if(!subj) {
fprintf(output, "Parse error.\n");
goto cert_out;
}
fprintf(output, "\tSubject DN:\t");
if(X509_NAME_print_ex_fp(output, subj, 0, XN_FLAG_COMPAT) != 1) {
fprintf(output, "Failed to write Subject DN.\n");
goto cert_out;
}
fprintf(output, "\n");
subj = X509_get_issuer_name(x509);
if(!subj) {
fprintf(output, "Parse error.\n");
goto cert_out;
}
fprintf(output, "\tIssuer DN:\t");
if(X509_NAME_print_ex_fp(output, subj, 0, XN_FLAG_COMPAT) != 1) {
fprintf(output, "Failed to write Issuer DN.\n");
goto cert_out;
}
fprintf(output, "\n");
if(X509_digest(x509, md, data, &md_len) != 1) {
fprintf(output, "Failed to digest data.\n");
goto cert_out;
}
fprintf(output, "\tFingerprint:\t");
dump_data(data, md_len, output, false, format_arg_hex);

bio = BIO_new_fp(output, BIO_NOCLOSE | BIO_FP_TEXT);
not_before = X509_get_notBefore(x509);
if(not_before) {
fprintf(output, "\tNot Before:\t");
if(ASN1_TIME_print(bio, not_before) != 1) {
fprintf(output, "Failed to write Not Before time.\n");
goto cert_out;
}
fprintf(output, "\n");
subj = X509_get_issuer_name(x509);
if(!subj) {
fprintf(output, "Parse error.\n");
goto cert_out;
}
fprintf(output, "\tIssuer DN:\t");
if(X509_NAME_print_ex_fp(output, subj, 0, XN_FLAG_COMPAT) != 1) {
fprintf(output, "Failed to write Issuer DN.\n");
}
not_after = X509_get_notAfter(x509);
if(not_after) {
fprintf(output, "\tNot After:\t");
if(ASN1_TIME_print(bio, not_after) != 1) {
fprintf(output, "Failed to write Not After time.\n");
goto cert_out;
}
fprintf(output, "\n");
if(X509_digest(x509, md, data, &md_len) != 1) {
fprintf(output, "Failed to digest data.\n");
goto cert_out;
}
fprintf(output, "\tFingerprint:\t");
dump_data(data, md_len, output, false, format_arg_hex);

bio = BIO_new_fp(output, BIO_NOCLOSE | BIO_FP_TEXT);
not_before = X509_get_notBefore(x509);
if(not_before) {
fprintf(output, "\tNot Before:\t");
if(ASN1_TIME_print(bio, not_before) != 1) {
fprintf(output, "Failed to write Not Before time.\n");
goto cert_out;
}
fprintf(output, "\n");
}
not_after = X509_get_notAfter(x509);
if(not_after) {
fprintf(output, "\tNot After:\t");
if(ASN1_TIME_print(bio, not_after) != 1) {
fprintf(output, "Failed to write Not After time.\n");
goto cert_out;
}
fprintf(output, "\n");
}
} else {
fprintf(output, "Parse error.\n");
return;
}
cert_out:
if(x509) {
Expand Down
27 changes: 10 additions & 17 deletions ykcs11/openssl_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,27 +107,20 @@ CK_RV do_rsa_encrypt(ykcs11_pkey_t *key, int padding, const ykcs11_md_t* oaep_md

CK_RV do_store_cert(CK_BYTE_PTR data, CK_ULONG len, ykcs11_x509_t **cert) {

const unsigned char *p = data; // Mandatory temp variable required by OpenSSL
unsigned long cert_len;

if (*p == TAG_CERT) {
unsigned char certdata[YKPIV_OBJ_MAX_SIZE * 10] = {0};
unsigned long certdata_len = sizeof (certdata);
if(ykpiv_util_get_certdata(data, len, certdata, &certdata_len) != YKPIV_OK) {
DBG("Failed to get certificate data");
return CKR_DATA_INVALID;
}
p = certdata;
cert_len = certdata_len;
} else {
// Raw certificate ...
cert_len = len;
unsigned char certdata[YKPIV_OBJ_MAX_SIZE * 10] = {0};
unsigned long certdata_len = sizeof (certdata);

if(ykpiv_util_get_certdata(data, len, certdata, &certdata_len) != YKPIV_OK) {
DBG("Failed to get certificate data");
return CKR_DATA_INVALID;
}

if(*cert)
if(*cert) {
X509_free(*cert);
}

*cert = d2i_X509(NULL, &p, cert_len);
const unsigned char *p = certdata; // Mandatory temp variable required by OpenSSL
*cert = d2i_X509(NULL, &p, certdata_len);
if (*cert == NULL)
return CKR_FUNCTION_FAILED;

Expand Down

0 comments on commit 9add8cc

Please sign in to comment.