static int store_func(hx509_context context, void *ctx, hx509_cert c) { struct store_ctx *sc = ctx; heim_octet_string data; int ret; ret = hx509_cert_binary(context, c, &data); if (ret) return ret; switch (sc->format) { case USE_DER: fwrite(data.data, data.length, 1, sc->f); free(data.data); break; case USE_PEM: hx509_pem_write(context, "CERTIFICATE", NULL, sc->f, data.data, data.length); free(data.data); if (_hx509_cert_private_key_exportable(c)) { hx509_private_key key = _hx509_cert_private_key(c); ret = _hx509_private_key_export(context, key, &data); if (ret) break; hx509_pem_write(context, _hx509_private_pem_name(key), NULL, sc->f, data.data, data.length); free(data.data); } break; } return 0; }
static int cert_process(hx509_context context, void *ctx, hx509_cert cert) { struct sigctx *sigctx = ctx; const unsigned int i = sigctx->sd.certificates->len; void *ptr; int ret; ptr = realloc(sigctx->sd.certificates->val, (i + 1) * sizeof(sigctx->sd.certificates->val[0])); if (ptr == NULL) return ENOMEM; sigctx->sd.certificates->val = ptr; ret = hx509_cert_binary(context, cert, &sigctx->sd.certificates->val[i]); if (ret == 0) sigctx->sd.certificates->len++; return ret; }
static int HX509_LIB_CALL add_cert(hx509_context hxctx, void *ctx, hx509_cert cert) { static char empty[] = ""; struct foo *foo = (struct foo *)ctx; struct st_object *o = NULL; CK_OBJECT_CLASS type; CK_BBOOL bool_true = CK_TRUE; CK_BBOOL bool_false = CK_FALSE; CK_CERTIFICATE_TYPE cert_type = CKC_X_509; CK_KEY_TYPE key_type; CK_MECHANISM_TYPE mech_type; CK_RV ret = CKR_GENERAL_ERROR; int hret; heim_octet_string cert_data, subject_data, issuer_data, serial_data; st_logf("adding certificate\n"); serial_data.data = NULL; serial_data.length = 0; cert_data = subject_data = issuer_data = serial_data; hret = hx509_cert_binary(hxctx, cert, &cert_data); if (hret) goto out; { hx509_name name; hret = hx509_cert_get_issuer(cert, &name); if (hret) goto out; hret = hx509_name_binary(name, &issuer_data); hx509_name_free(&name); if (hret) goto out; hret = hx509_cert_get_subject(cert, &name); if (hret) goto out; hret = hx509_name_binary(name, &subject_data); hx509_name_free(&name); if (hret) goto out; } { AlgorithmIdentifier alg; hret = hx509_cert_get_SPKI_AlgorithmIdentifier(context, cert, &alg); if (hret) { ret = CKR_DEVICE_MEMORY; goto out; } key_type = CKK_RSA; /* XXX */ free_AlgorithmIdentifier(&alg); } type = CKO_CERTIFICATE; o = add_st_object(); if (o == NULL) { ret = CKR_DEVICE_MEMORY; goto out; } o->cert = hx509_cert_ref(cert); add_object_attribute(o, 0, CKA_CLASS, &type, sizeof(type)); add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false)); add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false)); add_object_attribute(o, 0, CKA_LABEL, foo->label, strlen(foo->label)); add_object_attribute(o, 0, CKA_CERTIFICATE_TYPE, &cert_type, sizeof(cert_type)); add_object_attribute(o, 0, CKA_ID, foo->id, strlen(foo->id)); add_object_attribute(o, 0, CKA_SUBJECT, subject_data.data, subject_data.length); add_object_attribute(o, 0, CKA_ISSUER, issuer_data.data, issuer_data.length); add_object_attribute(o, 0, CKA_SERIAL_NUMBER, serial_data.data, serial_data.length); add_object_attribute(o, 0, CKA_VALUE, cert_data.data, cert_data.length); add_object_attribute(o, 0, CKA_TRUSTED, &bool_false, sizeof(bool_false)); st_logf("add cert ok: %lx\n", (unsigned long)OBJECT_ID(o)); type = CKO_PUBLIC_KEY; o = add_st_object(); if (o == NULL) { ret = CKR_DEVICE_MEMORY; goto out; } o->cert = hx509_cert_ref(cert); add_object_attribute(o, 0, CKA_CLASS, &type, sizeof(type)); add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false)); add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false)); add_object_attribute(o, 0, CKA_LABEL, foo->label, strlen(foo->label)); add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type)); add_object_attribute(o, 0, CKA_ID, foo->id, strlen(foo->id)); add_object_attribute(o, 0, CKA_START_DATE, empty, 1); /* XXX */ add_object_attribute(o, 0, CKA_END_DATE, empty, 1); /* XXX */ add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false)); add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false)); mech_type = CKM_RSA_X_509; add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type)); add_object_attribute(o, 0, CKA_SUBJECT, subject_data.data, subject_data.length); add_object_attribute(o, 0, CKA_ENCRYPT, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_VERIFY, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_VERIFY_RECOVER, &bool_false, sizeof(bool_false)); add_object_attribute(o, 0, CKA_WRAP, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_TRUSTED, &bool_true, sizeof(bool_true)); add_pubkey_info(hxctx, o, key_type, cert); st_logf("add key ok: %lx\n", (unsigned long)OBJECT_ID(o)); if (hx509_cert_have_private_key(cert)) { CK_FLAGS flags; type = CKO_PRIVATE_KEY; /* Note to static analyzers: `o' is still referred to via globals */ o = add_st_object(); if (o == NULL) { ret = CKR_DEVICE_MEMORY; goto out; } o->cert = hx509_cert_ref(cert); add_object_attribute(o, 0, CKA_CLASS, &type, sizeof(type)); add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_PRIVATE, &bool_true, sizeof(bool_false)); add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false)); add_object_attribute(o, 0, CKA_LABEL, foo->label, strlen(foo->label)); add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type)); add_object_attribute(o, 0, CKA_ID, foo->id, strlen(foo->id)); add_object_attribute(o, 0, CKA_START_DATE, empty, 1); /* XXX */ add_object_attribute(o, 0, CKA_END_DATE, empty, 1); /* XXX */ add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false)); add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false)); mech_type = CKM_RSA_X_509; add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type)); add_object_attribute(o, 0, CKA_SUBJECT, subject_data.data, subject_data.length); add_object_attribute(o, 0, CKA_SENSITIVE, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_SECONDARY_AUTH, &bool_false, sizeof(bool_true)); flags = 0; add_object_attribute(o, 0, CKA_AUTH_PIN_FLAGS, &flags, sizeof(flags)); add_object_attribute(o, 0, CKA_DECRYPT, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_SIGN, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_SIGN_RECOVER, &bool_false, sizeof(bool_false)); add_object_attribute(o, 0, CKA_UNWRAP, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_EXTRACTABLE, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_NEVER_EXTRACTABLE, &bool_false, sizeof(bool_false)); add_pubkey_info(hxctx, o, key_type, cert); } ret = CKR_OK; out: if (ret != CKR_OK) { st_logf("something went wrong when adding cert!\n"); /* XXX wack o */; } hx509_xfree(cert_data.data); hx509_xfree(serial_data.data); hx509_xfree(issuer_data.data); hx509_xfree(subject_data.data); /* Note to static analyzers: `o' is still referred to via globals */ return 0; }
static int store_func(hx509_context context, void *ctx, hx509_cert c) { PKCS12_AuthenticatedSafe *as = ctx; PKCS12_OctetString os; PKCS12_CertBag cb; size_t size; int ret; memset(&os, 0, sizeof(os)); memset(&cb, 0, sizeof(cb)); os.data = NULL; os.length = 0; ret = hx509_cert_binary(context, c, &os); if (ret) return ret; ASN1_MALLOC_ENCODE(PKCS12_OctetString, cb.certValue.data,cb.certValue.length, &os, &size, ret); free(os.data); if (ret) goto out; ret = der_copy_oid(&asn1_oid_id_pkcs_9_at_certTypes_x509, &cb.certType); if (ret) { free_PKCS12_CertBag(&cb); goto out; } ASN1_MALLOC_ENCODE(PKCS12_CertBag, os.data, os.length, &cb, &size, ret); free_PKCS12_CertBag(&cb); if (ret) goto out; ret = addBag(context, as, &asn1_oid_id_pkcs12_certBag, os.data, os.length); if (_hx509_cert_private_key_exportable(c)) { hx509_private_key key = _hx509_cert_private_key(c); PKCS8PrivateKeyInfo pki; memset(&pki, 0, sizeof(pki)); ret = der_parse_hex_heim_integer("00", &pki.version); if (ret) return ret; ret = _hx509_private_key_oid(context, key, &pki.privateKeyAlgorithm.algorithm); if (ret) { free_PKCS8PrivateKeyInfo(&pki); return ret; } ret = _hx509_private_key_export(context, _hx509_cert_private_key(c), HX509_KEY_FORMAT_DER, &pki.privateKey); if (ret) { free_PKCS8PrivateKeyInfo(&pki); return ret; } /* set attribute, asn1_oid_id_pkcs_9_at_localKeyId */ ASN1_MALLOC_ENCODE(PKCS8PrivateKeyInfo, os.data, os.length, &pki, &size, ret); free_PKCS8PrivateKeyInfo(&pki); if (ret) return ret; ret = addBag(context, as, &asn1_oid_id_pkcs12_keyBag, os.data, os.length); if (ret) return ret; } out: return ret; }