void sc_pkcs15_free_certificate(struct sc_pkcs15_cert *cert) { assert(cert != NULL); if (cert->key) sc_pkcs15_free_pubkey(cert->key); free(cert->subject); free(cert->issuer); free(cert->serial); free(cert->data); free(cert->crl); free(cert); }
int sc_pkcs15_pubkey_from_prvkey(struct sc_context *ctx, struct sc_pkcs15_prkey *prvkey, struct sc_pkcs15_pubkey **out) { struct sc_pkcs15_pubkey *pubkey; int rv = SC_SUCCESS; assert(prvkey && out); *out = NULL; pubkey = calloc(1, sizeof(struct sc_pkcs15_pubkey)); if (!pubkey) return SC_ERROR_OUT_OF_MEMORY; pubkey->algorithm = prvkey->algorithm; switch (prvkey->algorithm) { case SC_ALGORITHM_RSA: rv = sc_pkcs15_dup_bignum(&pubkey->u.rsa.modulus, &prvkey->u.rsa.modulus); if (!rv) rv = sc_pkcs15_dup_bignum(&pubkey->u.rsa.exponent, &prvkey->u.rsa.exponent); break; case SC_ALGORITHM_DSA: rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.pub, &prvkey->u.dsa.pub); if (!rv) rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.p, &prvkey->u.dsa.p); if (!rv) rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.q, &prvkey->u.dsa.q); if (!rv) rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.g, &prvkey->u.dsa.g); break; case SC_ALGORITHM_GOSTR3410: break; case SC_ALGORITHM_EC: pubkey->u.ec.ecpointQ.value = malloc(prvkey->u.ec.ecpointQ.len); memcpy(pubkey->u.ec.ecpointQ.value, prvkey->u.ec.ecpointQ.value, prvkey->u.ec.ecpointQ.len); pubkey->u.ec.ecpointQ.len = prvkey->u.ec.ecpointQ.len; break; default: sc_log(ctx, "Unsupported private key algorithm"); return SC_ERROR_NOT_SUPPORTED; } if (rv) sc_pkcs15_free_pubkey(pubkey); else *out = pubkey; return rv; }
static int read_public_key(void) { int r; struct sc_pkcs15_id id; struct sc_pkcs15_object *obj; sc_pkcs15_pubkey_t *pubkey = NULL; sc_pkcs15_cert_t *cert = NULL; sc_pkcs15_der_t pem_key; id.len = SC_PKCS15_MAX_ID_SIZE; sc_pkcs15_hex_string_to_id(opt_pubkey, &id); r = sc_pkcs15_find_pubkey_by_id(p15card, &id, &obj); if (r >= 0) { if (verbose) printf("Reading public key with ID '%s'\n", opt_pubkey); r = authenticate(obj); if (r >= 0) r = sc_pkcs15_read_pubkey(p15card, obj, &pubkey); } else if (r == SC_ERROR_OBJECT_NOT_FOUND) { /* No pubkey - try if there's a certificate */ r = sc_pkcs15_find_cert_by_id(p15card, &id, &obj); if (r >= 0) { if (verbose) printf("Reading certificate with ID '%s'\n", opt_pubkey); r = sc_pkcs15_read_certificate(p15card, (sc_pkcs15_cert_info_t *) obj->data, &cert); } if (r >= 0) pubkey = cert->key; } if (r == SC_ERROR_OBJECT_NOT_FOUND) { fprintf(stderr, "Public key with ID '%s' not found.\n", opt_pubkey); return 2; } if (r < 0) { fprintf(stderr, "Public key enumeration failed: %s\n", sc_strerror(r)); return 1; } if (!pubkey) { fprintf(stderr, "Public key not available\n"); return 1; } r = pubkey_pem_encode(pubkey, &pubkey->data, &pem_key); if (r < 0) { fprintf(stderr, "Error encoding PEM key: %s\n", sc_strerror(r)); r = 1; } else { r = print_pem_object("PUBLIC KEY", pem_key.value, pem_key.len); free(pem_key.value); } if (cert) sc_pkcs15_free_certificate(cert); else if (pubkey) sc_pkcs15_free_pubkey(pubkey); return r; }