1178825Sdfr/* 2233294Sstas * Copyright (c) 2004 - 2007 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 5178825Sdfr * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 9178825Sdfr * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 12178825Sdfr * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 16178825Sdfr * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 20178825Sdfr * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 32178825Sdfr */ 33178825Sdfr 34178825Sdfr#include "hx_locl.h" 35178825Sdfr 36178825Sdfrstruct hx509_crypto; 37178825Sdfr 38178825Sdfrstruct signature_alg; 39178825Sdfr 40178825Sdfrstruct hx509_generate_private_context { 41178825Sdfr const heim_oid *key_oid; 42178825Sdfr int isCA; 43178825Sdfr unsigned long num_bits; 44178825Sdfr}; 45178825Sdfr 46178825Sdfrstruct hx509_private_key_ops { 47178825Sdfr const char *pemtype; 48233294Sstas const heim_oid *key_oid; 49233294Sstas int (*available)(const hx509_private_key, 50233294Sstas const AlgorithmIdentifier *); 51178825Sdfr int (*get_spki)(hx509_context, 52178825Sdfr const hx509_private_key, 53178825Sdfr SubjectPublicKeyInfo *); 54178825Sdfr int (*export)(hx509_context context, 55178825Sdfr const hx509_private_key, 56233294Sstas hx509_key_format_t, 57178825Sdfr heim_octet_string *); 58233294Sstas int (*import)(hx509_context, const AlgorithmIdentifier *, 59233294Sstas const void *, size_t, hx509_key_format_t, 60233294Sstas hx509_private_key); 61178825Sdfr int (*generate_private_key)(hx509_context, 62178825Sdfr struct hx509_generate_private_context *, 63178825Sdfr hx509_private_key); 64178825Sdfr BIGNUM *(*get_internal)(hx509_context, hx509_private_key, const char *); 65178825Sdfr}; 66178825Sdfr 67178825Sdfrstruct hx509_private_key { 68178825Sdfr unsigned int ref; 69178825Sdfr const struct signature_alg *md; 70178825Sdfr const heim_oid *signature_alg; 71178825Sdfr union { 72178825Sdfr RSA *rsa; 73178825Sdfr void *keydata; 74233294Sstas#ifdef HAVE_OPENSSL 75233294Sstas EC_KEY *ecdsa; 76233294Sstas#endif 77178825Sdfr } private_key; 78178825Sdfr hx509_private_key_ops *ops; 79178825Sdfr}; 80178825Sdfr 81178825Sdfr/* 82178825Sdfr * 83178825Sdfr */ 84178825Sdfr 85178825Sdfrstruct signature_alg { 86178825Sdfr const char *name; 87233294Sstas const heim_oid *sig_oid; 88233294Sstas const AlgorithmIdentifier *sig_alg; 89233294Sstas const heim_oid *key_oid; 90233294Sstas const AlgorithmIdentifier *digest_alg; 91178825Sdfr int flags; 92233294Sstas#define PROVIDE_CONF 0x1 93233294Sstas#define REQUIRE_SIGNER 0x2 94233294Sstas#define SELF_SIGNED_OK 0x4 95178825Sdfr 96178825Sdfr#define SIG_DIGEST 0x100 97178825Sdfr#define SIG_PUBLIC_SIG 0x200 98178825Sdfr#define SIG_SECRET 0x400 99178825Sdfr 100178825Sdfr#define RA_RSA_USES_DIGEST_INFO 0x1000000 101178825Sdfr 102233294Sstas time_t best_before; /* refuse signature made after best before date */ 103233294Sstas const EVP_MD *(*evp_md)(void); 104178825Sdfr int (*verify_signature)(hx509_context context, 105178825Sdfr const struct signature_alg *, 106178825Sdfr const Certificate *, 107178825Sdfr const AlgorithmIdentifier *, 108178825Sdfr const heim_octet_string *, 109178825Sdfr const heim_octet_string *); 110178825Sdfr int (*create_signature)(hx509_context, 111178825Sdfr const struct signature_alg *, 112178825Sdfr const hx509_private_key, 113178825Sdfr const AlgorithmIdentifier *, 114178825Sdfr const heim_octet_string *, 115178825Sdfr AlgorithmIdentifier *, 116178825Sdfr heim_octet_string *); 117233294Sstas int digest_size; 118178825Sdfr}; 119178825Sdfr 120233294Sstasstatic const struct signature_alg * 121233294Sstasfind_sig_alg(const heim_oid *oid); 122233294Sstas 123178825Sdfr/* 124178825Sdfr * 125178825Sdfr */ 126178825Sdfr 127233294Sstasstatic const heim_octet_string null_entry_oid = { 2, rk_UNCONST("\x05\x00") }; 128233294Sstas 129233294Sstasstatic const unsigned sha512_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 3 }; 130233294Sstasconst AlgorithmIdentifier _hx509_signature_sha512_data = { 131233294Sstas { 9, rk_UNCONST(sha512_oid_tree) }, rk_UNCONST(&null_entry_oid) 132233294Sstas}; 133233294Sstas 134233294Sstasstatic const unsigned sha384_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 2 }; 135233294Sstasconst AlgorithmIdentifier _hx509_signature_sha384_data = { 136233294Sstas { 9, rk_UNCONST(sha384_oid_tree) }, rk_UNCONST(&null_entry_oid) 137233294Sstas}; 138233294Sstas 139233294Sstasstatic const unsigned sha256_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 1 }; 140233294Sstasconst AlgorithmIdentifier _hx509_signature_sha256_data = { 141233294Sstas { 9, rk_UNCONST(sha256_oid_tree) }, rk_UNCONST(&null_entry_oid) 142233294Sstas}; 143233294Sstas 144233294Sstasstatic const unsigned sha1_oid_tree[] = { 1, 3, 14, 3, 2, 26 }; 145233294Sstasconst AlgorithmIdentifier _hx509_signature_sha1_data = { 146233294Sstas { 6, rk_UNCONST(sha1_oid_tree) }, rk_UNCONST(&null_entry_oid) 147233294Sstas}; 148233294Sstas 149233294Sstasstatic const unsigned md5_oid_tree[] = { 1, 2, 840, 113549, 2, 5 }; 150233294Sstasconst AlgorithmIdentifier _hx509_signature_md5_data = { 151233294Sstas { 6, rk_UNCONST(md5_oid_tree) }, rk_UNCONST(&null_entry_oid) 152233294Sstas}; 153233294Sstas 154233294Sstasstatic const unsigned ecPublicKey[] ={ 1, 2, 840, 10045, 2, 1 }; 155233294Sstasconst AlgorithmIdentifier _hx509_signature_ecPublicKey = { 156233294Sstas { 6, rk_UNCONST(ecPublicKey) }, NULL 157233294Sstas}; 158233294Sstas 159233294Sstasstatic const unsigned ecdsa_with_sha256_oid[] ={ 1, 2, 840, 10045, 4, 3, 2 }; 160233294Sstasconst AlgorithmIdentifier _hx509_signature_ecdsa_with_sha256_data = { 161233294Sstas { 7, rk_UNCONST(ecdsa_with_sha256_oid) }, NULL 162233294Sstas}; 163233294Sstas 164233294Sstasstatic const unsigned ecdsa_with_sha1_oid[] ={ 1, 2, 840, 10045, 4, 1 }; 165233294Sstasconst AlgorithmIdentifier _hx509_signature_ecdsa_with_sha1_data = { 166233294Sstas { 6, rk_UNCONST(ecdsa_with_sha1_oid) }, NULL 167233294Sstas}; 168233294Sstas 169233294Sstasstatic const unsigned rsa_with_sha512_oid[] ={ 1, 2, 840, 113549, 1, 1, 13 }; 170233294Sstasconst AlgorithmIdentifier _hx509_signature_rsa_with_sha512_data = { 171233294Sstas { 7, rk_UNCONST(rsa_with_sha512_oid) }, NULL 172233294Sstas}; 173233294Sstas 174233294Sstasstatic const unsigned rsa_with_sha384_oid[] ={ 1, 2, 840, 113549, 1, 1, 12 }; 175233294Sstasconst AlgorithmIdentifier _hx509_signature_rsa_with_sha384_data = { 176233294Sstas { 7, rk_UNCONST(rsa_with_sha384_oid) }, NULL 177233294Sstas}; 178233294Sstas 179233294Sstasstatic const unsigned rsa_with_sha256_oid[] ={ 1, 2, 840, 113549, 1, 1, 11 }; 180233294Sstasconst AlgorithmIdentifier _hx509_signature_rsa_with_sha256_data = { 181233294Sstas { 7, rk_UNCONST(rsa_with_sha256_oid) }, NULL 182233294Sstas}; 183233294Sstas 184233294Sstasstatic const unsigned rsa_with_sha1_oid[] ={ 1, 2, 840, 113549, 1, 1, 5 }; 185233294Sstasconst AlgorithmIdentifier _hx509_signature_rsa_with_sha1_data = { 186233294Sstas { 7, rk_UNCONST(rsa_with_sha1_oid) }, NULL 187233294Sstas}; 188233294Sstas 189233294Sstasstatic const unsigned rsa_with_md5_oid[] ={ 1, 2, 840, 113549, 1, 1, 4 }; 190233294Sstasconst AlgorithmIdentifier _hx509_signature_rsa_with_md5_data = { 191233294Sstas { 7, rk_UNCONST(rsa_with_md5_oid) }, NULL 192233294Sstas}; 193233294Sstas 194233294Sstasstatic const unsigned rsa_oid[] ={ 1, 2, 840, 113549, 1, 1, 1 }; 195233294Sstasconst AlgorithmIdentifier _hx509_signature_rsa_data = { 196233294Sstas { 7, rk_UNCONST(rsa_oid) }, NULL 197233294Sstas}; 198233294Sstas 199233294Sstasstatic const unsigned rsa_pkcs1_x509_oid[] ={ 1, 2, 752, 43, 16, 1 }; 200233294Sstasconst AlgorithmIdentifier _hx509_signature_rsa_pkcs1_x509_data = { 201233294Sstas { 6, rk_UNCONST(rsa_pkcs1_x509_oid) }, NULL 202233294Sstas}; 203233294Sstas 204233294Sstasstatic const unsigned des_rsdi_ede3_cbc_oid[] ={ 1, 2, 840, 113549, 3, 7 }; 205233294Sstasconst AlgorithmIdentifier _hx509_des_rsdi_ede3_cbc_oid = { 206233294Sstas { 6, rk_UNCONST(des_rsdi_ede3_cbc_oid) }, NULL 207233294Sstas}; 208233294Sstas 209233294Sstasstatic const unsigned aes128_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 2 }; 210233294Sstasconst AlgorithmIdentifier _hx509_crypto_aes128_cbc_data = { 211233294Sstas { 9, rk_UNCONST(aes128_cbc_oid) }, NULL 212233294Sstas}; 213233294Sstas 214233294Sstasstatic const unsigned aes256_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 42 }; 215233294Sstasconst AlgorithmIdentifier _hx509_crypto_aes256_cbc_data = { 216233294Sstas { 9, rk_UNCONST(aes256_cbc_oid) }, NULL 217233294Sstas}; 218233294Sstas 219233294Sstas/* 220233294Sstas * 221233294Sstas */ 222233294Sstas 223178825Sdfrstatic BIGNUM * 224178825Sdfrheim_int2BN(const heim_integer *i) 225178825Sdfr{ 226178825Sdfr BIGNUM *bn; 227178825Sdfr 228178825Sdfr bn = BN_bin2bn(i->data, i->length, NULL); 229178825Sdfr BN_set_negative(bn, i->negative); 230178825Sdfr return bn; 231178825Sdfr} 232178825Sdfr 233178825Sdfr/* 234178825Sdfr * 235178825Sdfr */ 236178825Sdfr 237178825Sdfrstatic int 238178825Sdfrset_digest_alg(DigestAlgorithmIdentifier *id, 239178825Sdfr const heim_oid *oid, 240178825Sdfr const void *param, size_t length) 241178825Sdfr{ 242178825Sdfr int ret; 243178825Sdfr if (param) { 244178825Sdfr id->parameters = malloc(sizeof(*id->parameters)); 245178825Sdfr if (id->parameters == NULL) 246178825Sdfr return ENOMEM; 247178825Sdfr id->parameters->data = malloc(length); 248178825Sdfr if (id->parameters->data == NULL) { 249178825Sdfr free(id->parameters); 250178825Sdfr id->parameters = NULL; 251178825Sdfr return ENOMEM; 252178825Sdfr } 253178825Sdfr memcpy(id->parameters->data, param, length); 254178825Sdfr id->parameters->length = length; 255178825Sdfr } else 256178825Sdfr id->parameters = NULL; 257178825Sdfr ret = der_copy_oid(oid, &id->algorithm); 258178825Sdfr if (ret) { 259178825Sdfr if (id->parameters) { 260178825Sdfr free(id->parameters->data); 261178825Sdfr free(id->parameters); 262178825Sdfr id->parameters = NULL; 263178825Sdfr } 264178825Sdfr return ret; 265178825Sdfr } 266178825Sdfr return 0; 267178825Sdfr} 268178825Sdfr 269233294Sstas#ifdef HAVE_OPENSSL 270233294Sstas 271233294Sstasstatic int 272233294Sstasheim_oid2ecnid(heim_oid *oid) 273233294Sstas{ 274233294Sstas /* 275233294Sstas * Now map to openssl OID fun 276233294Sstas */ 277233294Sstas 278233294Sstas if (der_heim_oid_cmp(oid, ASN1_OID_ID_EC_GROUP_SECP256R1) == 0) 279233294Sstas return NID_X9_62_prime256v1; 280233294Sstas else if (der_heim_oid_cmp(oid, ASN1_OID_ID_EC_GROUP_SECP160R1) == 0) 281233294Sstas return NID_secp160r1; 282233294Sstas else if (der_heim_oid_cmp(oid, ASN1_OID_ID_EC_GROUP_SECP160R2) == 0) 283233294Sstas return NID_secp160r2; 284233294Sstas 285233294Sstas return -1; 286233294Sstas} 287233294Sstas 288233294Sstasstatic int 289233294Sstasparse_ECParameters(hx509_context context, 290233294Sstas heim_octet_string *parameters, int *nid) 291233294Sstas{ 292233294Sstas ECParameters ecparam; 293233294Sstas size_t size; 294233294Sstas int ret; 295233294Sstas 296233294Sstas if (parameters == NULL) { 297233294Sstas ret = HX509_PARSING_KEY_FAILED; 298233294Sstas hx509_set_error_string(context, 0, ret, 299233294Sstas "EC parameters missing"); 300233294Sstas return ret; 301233294Sstas } 302233294Sstas 303233294Sstas ret = decode_ECParameters(parameters->data, parameters->length, 304233294Sstas &ecparam, &size); 305233294Sstas if (ret) { 306233294Sstas hx509_set_error_string(context, 0, ret, 307233294Sstas "Failed to decode EC parameters"); 308233294Sstas return ret; 309233294Sstas } 310233294Sstas 311233294Sstas if (ecparam.element != choice_ECParameters_namedCurve) { 312233294Sstas free_ECParameters(&ecparam); 313233294Sstas hx509_set_error_string(context, 0, ret, 314233294Sstas "EC parameters is not a named curve"); 315233294Sstas return HX509_CRYPTO_SIG_INVALID_FORMAT; 316233294Sstas } 317233294Sstas 318233294Sstas *nid = heim_oid2ecnid(&ecparam.u.namedCurve); 319233294Sstas free_ECParameters(&ecparam); 320233294Sstas if (*nid == -1) { 321233294Sstas hx509_set_error_string(context, 0, ret, 322233294Sstas "Failed to find matcing NID for EC curve"); 323233294Sstas return HX509_CRYPTO_SIG_INVALID_FORMAT; 324233294Sstas } 325233294Sstas return 0; 326233294Sstas} 327233294Sstas 328233294Sstas 329178825Sdfr/* 330178825Sdfr * 331178825Sdfr */ 332178825Sdfr 333178825Sdfrstatic int 334233294Sstasecdsa_verify_signature(hx509_context context, 335233294Sstas const struct signature_alg *sig_alg, 336233294Sstas const Certificate *signer, 337233294Sstas const AlgorithmIdentifier *alg, 338233294Sstas const heim_octet_string *data, 339233294Sstas const heim_octet_string *sig) 340233294Sstas{ 341233294Sstas const AlgorithmIdentifier *digest_alg; 342233294Sstas const SubjectPublicKeyInfo *spi; 343233294Sstas heim_octet_string digest; 344233294Sstas int ret; 345233294Sstas EC_KEY *key = NULL; 346233294Sstas int groupnid; 347233294Sstas EC_GROUP *group; 348233294Sstas const unsigned char *p; 349233294Sstas long len; 350233294Sstas 351233294Sstas digest_alg = sig_alg->digest_alg; 352233294Sstas 353233294Sstas ret = _hx509_create_signature(context, 354233294Sstas NULL, 355233294Sstas digest_alg, 356233294Sstas data, 357233294Sstas NULL, 358233294Sstas &digest); 359233294Sstas if (ret) 360233294Sstas return ret; 361233294Sstas 362233294Sstas /* set up EC KEY */ 363233294Sstas spi = &signer->tbsCertificate.subjectPublicKeyInfo; 364233294Sstas 365233294Sstas if (der_heim_oid_cmp(&spi->algorithm.algorithm, ASN1_OID_ID_ECPUBLICKEY) != 0) 366233294Sstas return HX509_CRYPTO_SIG_INVALID_FORMAT; 367233294Sstas 368233294Sstas#ifdef HAVE_OPENSSL 369233294Sstas /* 370233294Sstas * Find the group id 371233294Sstas */ 372233294Sstas 373233294Sstas ret = parse_ECParameters(context, spi->algorithm.parameters, &groupnid); 374233294Sstas if (ret) { 375233294Sstas der_free_octet_string(&digest); 376233294Sstas return ret; 377233294Sstas } 378233294Sstas 379233294Sstas /* 380233294Sstas * Create group, key, parse key 381233294Sstas */ 382233294Sstas 383233294Sstas key = EC_KEY_new(); 384233294Sstas group = EC_GROUP_new_by_curve_name(groupnid); 385233294Sstas EC_KEY_set_group(key, group); 386233294Sstas EC_GROUP_free(group); 387233294Sstas 388233294Sstas p = spi->subjectPublicKey.data; 389233294Sstas len = spi->subjectPublicKey.length / 8; 390233294Sstas 391233294Sstas if (o2i_ECPublicKey(&key, &p, len) == NULL) { 392233294Sstas EC_KEY_free(key); 393233294Sstas return HX509_CRYPTO_SIG_INVALID_FORMAT; 394233294Sstas } 395233294Sstas#else 396233294Sstas key = SubjectPublicKeyInfo2EC_KEY(spi); 397233294Sstas#endif 398233294Sstas 399233294Sstas ret = ECDSA_verify(-1, digest.data, digest.length, 400233294Sstas sig->data, sig->length, key); 401233294Sstas der_free_octet_string(&digest); 402233294Sstas EC_KEY_free(key); 403233294Sstas if (ret != 1) { 404233294Sstas ret = HX509_CRYPTO_SIG_INVALID_FORMAT; 405233294Sstas return ret; 406233294Sstas } 407233294Sstas 408233294Sstas return 0; 409233294Sstas} 410233294Sstas 411233294Sstasstatic int 412233294Sstasecdsa_create_signature(hx509_context context, 413233294Sstas const struct signature_alg *sig_alg, 414233294Sstas const hx509_private_key signer, 415233294Sstas const AlgorithmIdentifier *alg, 416233294Sstas const heim_octet_string *data, 417233294Sstas AlgorithmIdentifier *signatureAlgorithm, 418233294Sstas heim_octet_string *sig) 419233294Sstas{ 420233294Sstas const AlgorithmIdentifier *digest_alg; 421233294Sstas heim_octet_string indata; 422233294Sstas const heim_oid *sig_oid; 423233294Sstas unsigned int siglen; 424233294Sstas int ret; 425233294Sstas 426233294Sstas if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) != 0) 427233294Sstas _hx509_abort("internal error passing private key to wrong ops"); 428233294Sstas 429233294Sstas sig_oid = sig_alg->sig_oid; 430233294Sstas digest_alg = sig_alg->digest_alg; 431233294Sstas 432233294Sstas if (signatureAlgorithm) { 433233294Sstas ret = set_digest_alg(signatureAlgorithm, sig_oid, "\x05\x00", 2); 434233294Sstas if (ret) { 435233294Sstas hx509_clear_error_string(context); 436233294Sstas goto error; 437233294Sstas } 438233294Sstas } 439233294Sstas 440233294Sstas ret = _hx509_create_signature(context, 441233294Sstas NULL, 442233294Sstas digest_alg, 443233294Sstas data, 444233294Sstas NULL, 445233294Sstas &indata); 446233294Sstas if (ret) { 447233294Sstas if (signatureAlgorithm) 448233294Sstas free_AlgorithmIdentifier(signatureAlgorithm); 449233294Sstas goto error; 450233294Sstas } 451233294Sstas 452233294Sstas sig->length = ECDSA_size(signer->private_key.ecdsa); 453233294Sstas sig->data = malloc(sig->length); 454233294Sstas if (sig->data == NULL) { 455233294Sstas der_free_octet_string(&indata); 456233294Sstas ret = ENOMEM; 457233294Sstas hx509_set_error_string(context, 0, ret, "out of memory"); 458233294Sstas goto error; 459233294Sstas } 460233294Sstas 461233294Sstas siglen = sig->length; 462233294Sstas 463233294Sstas ret = ECDSA_sign(-1, indata.data, indata.length, 464233294Sstas sig->data, &siglen, signer->private_key.ecdsa); 465233294Sstas der_free_octet_string(&indata); 466233294Sstas if (ret != 1) { 467233294Sstas ret = HX509_CMS_FAILED_CREATE_SIGATURE; 468233294Sstas hx509_set_error_string(context, 0, ret, 469233294Sstas "ECDSA sign failed: %d", ret); 470233294Sstas goto error; 471233294Sstas } 472233294Sstas if (siglen > sig->length) 473233294Sstas _hx509_abort("ECDSA signature prelen longer the output len"); 474233294Sstas 475233294Sstas sig->length = siglen; 476233294Sstas 477233294Sstas return 0; 478233294Sstas error: 479233294Sstas if (signatureAlgorithm) 480233294Sstas free_AlgorithmIdentifier(signatureAlgorithm); 481233294Sstas return ret; 482233294Sstas} 483233294Sstas 484233294Sstasstatic int 485233294Sstasecdsa_available(const hx509_private_key signer, 486233294Sstas const AlgorithmIdentifier *sig_alg) 487233294Sstas{ 488233294Sstas const struct signature_alg *sig; 489233294Sstas const EC_GROUP *group; 490233294Sstas BN_CTX *bnctx = NULL; 491233294Sstas BIGNUM *order = NULL; 492233294Sstas int ret = 0; 493233294Sstas 494233294Sstas if (der_heim_oid_cmp(signer->ops->key_oid, &asn1_oid_id_ecPublicKey) != 0) 495233294Sstas _hx509_abort("internal error passing private key to wrong ops"); 496233294Sstas 497233294Sstas sig = find_sig_alg(&sig_alg->algorithm); 498233294Sstas 499233294Sstas if (sig == NULL || sig->digest_size == 0) 500233294Sstas return 0; 501233294Sstas 502233294Sstas group = EC_KEY_get0_group(signer->private_key.ecdsa); 503233294Sstas if (group == NULL) 504233294Sstas return 0; 505233294Sstas 506233294Sstas bnctx = BN_CTX_new(); 507233294Sstas order = BN_new(); 508233294Sstas if (order == NULL) 509233294Sstas goto err; 510233294Sstas 511233294Sstas if (EC_GROUP_get_order(group, order, bnctx) != 1) 512233294Sstas goto err; 513233294Sstas 514233294Sstas if (BN_num_bytes(order) > sig->digest_size) 515233294Sstas ret = 1; 516233294Sstas err: 517233294Sstas if (bnctx) 518233294Sstas BN_CTX_free(bnctx); 519233294Sstas if (order) 520233294Sstas BN_clear_free(order); 521233294Sstas 522233294Sstas return ret; 523233294Sstas} 524233294Sstas 525233294Sstas 526233294Sstas#endif /* HAVE_OPENSSL */ 527233294Sstas 528233294Sstas/* 529233294Sstas * 530233294Sstas */ 531233294Sstas 532233294Sstasstatic int 533178825Sdfrrsa_verify_signature(hx509_context context, 534178825Sdfr const struct signature_alg *sig_alg, 535178825Sdfr const Certificate *signer, 536178825Sdfr const AlgorithmIdentifier *alg, 537178825Sdfr const heim_octet_string *data, 538178825Sdfr const heim_octet_string *sig) 539178825Sdfr{ 540178825Sdfr const SubjectPublicKeyInfo *spi; 541178825Sdfr DigestInfo di; 542178825Sdfr unsigned char *to; 543178825Sdfr int tosize, retsize; 544178825Sdfr int ret; 545178825Sdfr RSA *rsa; 546178825Sdfr size_t size; 547233294Sstas const unsigned char *p; 548178825Sdfr 549178825Sdfr memset(&di, 0, sizeof(di)); 550178825Sdfr 551178825Sdfr spi = &signer->tbsCertificate.subjectPublicKeyInfo; 552178825Sdfr 553233294Sstas p = spi->subjectPublicKey.data; 554233294Sstas size = spi->subjectPublicKey.length / 8; 555233294Sstas 556233294Sstas rsa = d2i_RSAPublicKey(NULL, &p, size); 557178825Sdfr if (rsa == NULL) { 558178825Sdfr ret = ENOMEM; 559178825Sdfr hx509_set_error_string(context, 0, ret, "out of memory"); 560178825Sdfr goto out; 561178825Sdfr } 562178825Sdfr 563178825Sdfr tosize = RSA_size(rsa); 564178825Sdfr to = malloc(tosize); 565178825Sdfr if (to == NULL) { 566178825Sdfr ret = ENOMEM; 567178825Sdfr hx509_set_error_string(context, 0, ret, "out of memory"); 568178825Sdfr goto out; 569178825Sdfr } 570178825Sdfr 571233294Sstas retsize = RSA_public_decrypt(sig->length, (unsigned char *)sig->data, 572178825Sdfr to, rsa, RSA_PKCS1_PADDING); 573178825Sdfr if (retsize <= 0) { 574178825Sdfr ret = HX509_CRYPTO_SIG_INVALID_FORMAT; 575233294Sstas hx509_set_error_string(context, 0, ret, 576178825Sdfr "RSA public decrypt failed: %d", retsize); 577178825Sdfr free(to); 578178825Sdfr goto out; 579178825Sdfr } 580178825Sdfr if (retsize > tosize) 581178825Sdfr _hx509_abort("internal rsa decryption failure: ret > tosize"); 582178825Sdfr 583178825Sdfr if (sig_alg->flags & RA_RSA_USES_DIGEST_INFO) { 584178825Sdfr 585178825Sdfr ret = decode_DigestInfo(to, retsize, &di, &size); 586178825Sdfr free(to); 587178825Sdfr if (ret) { 588178825Sdfr goto out; 589178825Sdfr } 590233294Sstas 591178825Sdfr /* Check for extra data inside the sigature */ 592233294Sstas if (size != (size_t)retsize) { 593178825Sdfr ret = HX509_CRYPTO_SIG_INVALID_FORMAT; 594178825Sdfr hx509_set_error_string(context, 0, ret, "size from decryption mismatch"); 595178825Sdfr goto out; 596178825Sdfr } 597233294Sstas 598233294Sstas if (sig_alg->digest_alg && 599233294Sstas der_heim_oid_cmp(&di.digestAlgorithm.algorithm, 600233294Sstas &sig_alg->digest_alg->algorithm) != 0) 601178825Sdfr { 602178825Sdfr ret = HX509_CRYPTO_OID_MISMATCH; 603178825Sdfr hx509_set_error_string(context, 0, ret, "object identifier in RSA sig mismatch"); 604178825Sdfr goto out; 605178825Sdfr } 606233294Sstas 607178825Sdfr /* verify that the parameters are NULL or the NULL-type */ 608178825Sdfr if (di.digestAlgorithm.parameters != NULL && 609178825Sdfr (di.digestAlgorithm.parameters->length != 2 || 610178825Sdfr memcmp(di.digestAlgorithm.parameters->data, "\x05\x00", 2) != 0)) 611178825Sdfr { 612178825Sdfr ret = HX509_CRYPTO_SIG_INVALID_FORMAT; 613178825Sdfr hx509_set_error_string(context, 0, ret, "Extra parameters inside RSA signature"); 614178825Sdfr goto out; 615178825Sdfr } 616178825Sdfr 617178825Sdfr ret = _hx509_verify_signature(context, 618178825Sdfr NULL, 619178825Sdfr &di.digestAlgorithm, 620178825Sdfr data, 621178825Sdfr &di.digest); 622178825Sdfr } else { 623233294Sstas if ((size_t)retsize != data->length || 624233294Sstas ct_memcmp(to, data->data, retsize) != 0) 625178825Sdfr { 626178825Sdfr ret = HX509_CRYPTO_SIG_INVALID_FORMAT; 627178825Sdfr hx509_set_error_string(context, 0, ret, "RSA Signature incorrect"); 628178825Sdfr goto out; 629178825Sdfr } 630178825Sdfr free(to); 631178825Sdfr } 632233294Sstas ret = 0; 633178825Sdfr 634178825Sdfr out: 635178825Sdfr free_DigestInfo(&di); 636233294Sstas if (rsa) 637233294Sstas RSA_free(rsa); 638178825Sdfr return ret; 639178825Sdfr} 640178825Sdfr 641178825Sdfrstatic int 642178825Sdfrrsa_create_signature(hx509_context context, 643178825Sdfr const struct signature_alg *sig_alg, 644178825Sdfr const hx509_private_key signer, 645178825Sdfr const AlgorithmIdentifier *alg, 646178825Sdfr const heim_octet_string *data, 647178825Sdfr AlgorithmIdentifier *signatureAlgorithm, 648178825Sdfr heim_octet_string *sig) 649178825Sdfr{ 650178825Sdfr const AlgorithmIdentifier *digest_alg; 651178825Sdfr heim_octet_string indata; 652178825Sdfr const heim_oid *sig_oid; 653178825Sdfr size_t size; 654178825Sdfr int ret; 655233294Sstas 656233294Sstas if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) != 0) 657233294Sstas return HX509_ALG_NOT_SUPP; 658233294Sstas 659178825Sdfr if (alg) 660178825Sdfr sig_oid = &alg->algorithm; 661178825Sdfr else 662178825Sdfr sig_oid = signer->signature_alg; 663178825Sdfr 664233294Sstas if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA512WITHRSAENCRYPTION) == 0) { 665233294Sstas digest_alg = hx509_signature_sha512(); 666233294Sstas } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA384WITHRSAENCRYPTION) == 0) { 667233294Sstas digest_alg = hx509_signature_sha384(); 668233294Sstas } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA256WITHRSAENCRYPTION) == 0) { 669178825Sdfr digest_alg = hx509_signature_sha256(); 670233294Sstas } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION) == 0) { 671178825Sdfr digest_alg = hx509_signature_sha1(); 672233294Sstas } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION) == 0) { 673178825Sdfr digest_alg = hx509_signature_md5(); 674233294Sstas } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION) == 0) { 675178825Sdfr digest_alg = hx509_signature_md5(); 676233294Sstas } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_DSA_WITH_SHA1) == 0) { 677178825Sdfr digest_alg = hx509_signature_sha1(); 678233294Sstas } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0) { 679178825Sdfr digest_alg = hx509_signature_sha1(); 680233294Sstas } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_HEIM_RSA_PKCS1_X509) == 0) { 681178825Sdfr digest_alg = NULL; 682178825Sdfr } else 683178825Sdfr return HX509_ALG_NOT_SUPP; 684178825Sdfr 685178825Sdfr if (signatureAlgorithm) { 686178825Sdfr ret = set_digest_alg(signatureAlgorithm, sig_oid, "\x05\x00", 2); 687178825Sdfr if (ret) { 688178825Sdfr hx509_clear_error_string(context); 689178825Sdfr return ret; 690178825Sdfr } 691178825Sdfr } 692178825Sdfr 693178825Sdfr if (digest_alg) { 694178825Sdfr DigestInfo di; 695178825Sdfr memset(&di, 0, sizeof(di)); 696178825Sdfr 697178825Sdfr ret = _hx509_create_signature(context, 698178825Sdfr NULL, 699178825Sdfr digest_alg, 700178825Sdfr data, 701178825Sdfr &di.digestAlgorithm, 702178825Sdfr &di.digest); 703178825Sdfr if (ret) 704178825Sdfr return ret; 705178825Sdfr ASN1_MALLOC_ENCODE(DigestInfo, 706178825Sdfr indata.data, 707178825Sdfr indata.length, 708178825Sdfr &di, 709178825Sdfr &size, 710178825Sdfr ret); 711178825Sdfr free_DigestInfo(&di); 712178825Sdfr if (ret) { 713178825Sdfr hx509_set_error_string(context, 0, ret, "out of memory"); 714178825Sdfr return ret; 715178825Sdfr } 716178825Sdfr if (indata.length != size) 717178825Sdfr _hx509_abort("internal ASN.1 encoder error"); 718178825Sdfr } else { 719178825Sdfr indata = *data; 720178825Sdfr } 721178825Sdfr 722178825Sdfr sig->length = RSA_size(signer->private_key.rsa); 723178825Sdfr sig->data = malloc(sig->length); 724178825Sdfr if (sig->data == NULL) { 725178825Sdfr der_free_octet_string(&indata); 726178825Sdfr hx509_set_error_string(context, 0, ENOMEM, "out of memory"); 727178825Sdfr return ENOMEM; 728178825Sdfr } 729178825Sdfr 730233294Sstas ret = RSA_private_encrypt(indata.length, indata.data, 731233294Sstas sig->data, 732178825Sdfr signer->private_key.rsa, 733178825Sdfr RSA_PKCS1_PADDING); 734178825Sdfr if (indata.data != data->data) 735178825Sdfr der_free_octet_string(&indata); 736178825Sdfr if (ret <= 0) { 737178825Sdfr ret = HX509_CMS_FAILED_CREATE_SIGATURE; 738178825Sdfr hx509_set_error_string(context, 0, ret, 739233294Sstas "RSA private encrypt failed: %d", ret); 740178825Sdfr return ret; 741178825Sdfr } 742233294Sstas if ((size_t)ret > sig->length) 743178825Sdfr _hx509_abort("RSA signature prelen longer the output len"); 744178825Sdfr 745178825Sdfr sig->length = ret; 746233294Sstas 747178825Sdfr return 0; 748178825Sdfr} 749178825Sdfr 750178825Sdfrstatic int 751178825Sdfrrsa_private_key_import(hx509_context context, 752233294Sstas const AlgorithmIdentifier *keyai, 753178825Sdfr const void *data, 754178825Sdfr size_t len, 755233294Sstas hx509_key_format_t format, 756178825Sdfr hx509_private_key private_key) 757178825Sdfr{ 758233294Sstas switch (format) { 759233294Sstas case HX509_KEY_FORMAT_DER: { 760233294Sstas const unsigned char *p = data; 761178825Sdfr 762233294Sstas private_key->private_key.rsa = 763233294Sstas d2i_RSAPrivateKey(NULL, &p, len); 764233294Sstas if (private_key->private_key.rsa == NULL) { 765233294Sstas hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED, 766233294Sstas "Failed to parse RSA key"); 767233294Sstas return HX509_PARSING_KEY_FAILED; 768233294Sstas } 769233294Sstas private_key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION; 770233294Sstas break; 771233294Sstas 772178825Sdfr } 773233294Sstas default: 774233294Sstas return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED; 775233294Sstas } 776178825Sdfr 777178825Sdfr return 0; 778178825Sdfr} 779178825Sdfr 780178825Sdfrstatic int 781178825Sdfrrsa_private_key2SPKI(hx509_context context, 782178825Sdfr hx509_private_key private_key, 783178825Sdfr SubjectPublicKeyInfo *spki) 784178825Sdfr{ 785178825Sdfr int len, ret; 786178825Sdfr 787178825Sdfr memset(spki, 0, sizeof(*spki)); 788178825Sdfr 789178825Sdfr len = i2d_RSAPublicKey(private_key->private_key.rsa, NULL); 790178825Sdfr 791178825Sdfr spki->subjectPublicKey.data = malloc(len); 792178825Sdfr if (spki->subjectPublicKey.data == NULL) { 793178825Sdfr hx509_set_error_string(context, 0, ENOMEM, "malloc - out of memory"); 794178825Sdfr return ENOMEM; 795178825Sdfr } 796178825Sdfr spki->subjectPublicKey.length = len * 8; 797178825Sdfr 798233294Sstas ret = set_digest_alg(&spki->algorithm, ASN1_OID_ID_PKCS1_RSAENCRYPTION, 799178825Sdfr "\x05\x00", 2); 800178825Sdfr if (ret) { 801178825Sdfr hx509_set_error_string(context, 0, ret, "malloc - out of memory"); 802178825Sdfr free(spki->subjectPublicKey.data); 803178825Sdfr spki->subjectPublicKey.data = NULL; 804178825Sdfr spki->subjectPublicKey.length = 0; 805178825Sdfr return ret; 806178825Sdfr } 807178825Sdfr 808178825Sdfr { 809178825Sdfr unsigned char *pp = spki->subjectPublicKey.data; 810178825Sdfr i2d_RSAPublicKey(private_key->private_key.rsa, &pp); 811178825Sdfr } 812178825Sdfr 813178825Sdfr return 0; 814178825Sdfr} 815178825Sdfr 816178825Sdfrstatic int 817233294Sstasrsa_generate_private_key(hx509_context context, 818178825Sdfr struct hx509_generate_private_context *ctx, 819178825Sdfr hx509_private_key private_key) 820178825Sdfr{ 821178825Sdfr BIGNUM *e; 822178825Sdfr int ret; 823178825Sdfr unsigned long bits; 824178825Sdfr 825178825Sdfr static const int default_rsa_e = 65537; 826233294Sstas static const int default_rsa_bits = 2048; 827178825Sdfr 828178825Sdfr private_key->private_key.rsa = RSA_new(); 829178825Sdfr if (private_key->private_key.rsa == NULL) { 830178825Sdfr hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED, 831178825Sdfr "Failed to generate RSA key"); 832178825Sdfr return HX509_PARSING_KEY_FAILED; 833178825Sdfr } 834233294Sstas 835178825Sdfr e = BN_new(); 836178825Sdfr BN_set_word(e, default_rsa_e); 837178825Sdfr 838178825Sdfr bits = default_rsa_bits; 839178825Sdfr 840178825Sdfr if (ctx->num_bits) 841178825Sdfr bits = ctx->num_bits; 842178825Sdfr 843178825Sdfr ret = RSA_generate_key_ex(private_key->private_key.rsa, bits, e, NULL); 844178825Sdfr BN_free(e); 845178825Sdfr if (ret != 1) { 846178825Sdfr hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED, 847178825Sdfr "Failed to generate RSA key"); 848178825Sdfr return HX509_PARSING_KEY_FAILED; 849178825Sdfr } 850233294Sstas private_key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION; 851178825Sdfr 852178825Sdfr return 0; 853178825Sdfr} 854178825Sdfr 855233294Sstasstatic int 856178825Sdfrrsa_private_key_export(hx509_context context, 857178825Sdfr const hx509_private_key key, 858233294Sstas hx509_key_format_t format, 859178825Sdfr heim_octet_string *data) 860178825Sdfr{ 861178825Sdfr int ret; 862178825Sdfr 863178825Sdfr data->data = NULL; 864178825Sdfr data->length = 0; 865178825Sdfr 866233294Sstas switch (format) { 867233294Sstas case HX509_KEY_FORMAT_DER: 868233294Sstas 869233294Sstas ret = i2d_RSAPrivateKey(key->private_key.rsa, NULL); 870233294Sstas if (ret <= 0) { 871233294Sstas ret = EINVAL; 872233294Sstas hx509_set_error_string(context, 0, ret, 873178825Sdfr "Private key is not exportable"); 874233294Sstas return ret; 875233294Sstas } 876178825Sdfr 877233294Sstas data->data = malloc(ret); 878233294Sstas if (data->data == NULL) { 879233294Sstas ret = ENOMEM; 880233294Sstas hx509_set_error_string(context, 0, ret, "malloc out of memory"); 881233294Sstas return ret; 882233294Sstas } 883233294Sstas data->length = ret; 884233294Sstas 885233294Sstas { 886233294Sstas unsigned char *p = data->data; 887233294Sstas i2d_RSAPrivateKey(key->private_key.rsa, &p); 888233294Sstas } 889233294Sstas break; 890233294Sstas default: 891233294Sstas return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED; 892178825Sdfr } 893178825Sdfr 894178825Sdfr return 0; 895178825Sdfr} 896178825Sdfr 897178825Sdfrstatic BIGNUM * 898233294Sstasrsa_get_internal(hx509_context context, 899233294Sstas hx509_private_key key, 900233294Sstas const char *type) 901178825Sdfr{ 902178825Sdfr if (strcasecmp(type, "rsa-modulus") == 0) { 903178825Sdfr return BN_dup(key->private_key.rsa->n); 904178825Sdfr } else if (strcasecmp(type, "rsa-exponent") == 0) { 905178825Sdfr return BN_dup(key->private_key.rsa->e); 906178825Sdfr } else 907178825Sdfr return NULL; 908178825Sdfr} 909178825Sdfr 910178825Sdfr 911178825Sdfr 912178825Sdfrstatic hx509_private_key_ops rsa_private_key_ops = { 913178825Sdfr "RSA PRIVATE KEY", 914233294Sstas ASN1_OID_ID_PKCS1_RSAENCRYPTION, 915233294Sstas NULL, 916178825Sdfr rsa_private_key2SPKI, 917178825Sdfr rsa_private_key_export, 918178825Sdfr rsa_private_key_import, 919178825Sdfr rsa_generate_private_key, 920178825Sdfr rsa_get_internal 921178825Sdfr}; 922178825Sdfr 923233294Sstas#ifdef HAVE_OPENSSL 924178825Sdfr 925233294Sstasstatic int 926233294Sstasecdsa_private_key2SPKI(hx509_context context, 927233294Sstas hx509_private_key private_key, 928233294Sstas SubjectPublicKeyInfo *spki) 929233294Sstas{ 930233294Sstas memset(spki, 0, sizeof(*spki)); 931233294Sstas return ENOMEM; 932233294Sstas} 933233294Sstas 934233294Sstasstatic int 935233294Sstasecdsa_private_key_export(hx509_context context, 936233294Sstas const hx509_private_key key, 937233294Sstas hx509_key_format_t format, 938233294Sstas heim_octet_string *data) 939233294Sstas{ 940233294Sstas return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED; 941233294Sstas} 942233294Sstas 943233294Sstasstatic int 944233294Sstasecdsa_private_key_import(hx509_context context, 945233294Sstas const AlgorithmIdentifier *keyai, 946233294Sstas const void *data, 947233294Sstas size_t len, 948233294Sstas hx509_key_format_t format, 949233294Sstas hx509_private_key private_key) 950233294Sstas{ 951233294Sstas const unsigned char *p = data; 952233294Sstas EC_KEY **pkey = NULL; 953233294Sstas 954233294Sstas if (keyai->parameters) { 955233294Sstas EC_GROUP *group; 956233294Sstas int groupnid; 957233294Sstas EC_KEY *key; 958233294Sstas int ret; 959233294Sstas 960233294Sstas ret = parse_ECParameters(context, keyai->parameters, &groupnid); 961233294Sstas if (ret) 962233294Sstas return ret; 963233294Sstas 964233294Sstas key = EC_KEY_new(); 965233294Sstas if (key == NULL) 966233294Sstas return ENOMEM; 967233294Sstas 968233294Sstas group = EC_GROUP_new_by_curve_name(groupnid); 969233294Sstas if (group == NULL) { 970233294Sstas EC_KEY_free(key); 971233294Sstas return ENOMEM; 972233294Sstas } 973233294Sstas EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); 974233294Sstas if (EC_KEY_set_group(key, group) == 0) { 975233294Sstas EC_KEY_free(key); 976233294Sstas EC_GROUP_free(group); 977233294Sstas return ENOMEM; 978233294Sstas } 979233294Sstas EC_GROUP_free(group); 980233294Sstas pkey = &key; 981233294Sstas } 982233294Sstas 983233294Sstas switch (format) { 984233294Sstas case HX509_KEY_FORMAT_DER: 985233294Sstas 986233294Sstas private_key->private_key.ecdsa = d2i_ECPrivateKey(pkey, &p, len); 987233294Sstas if (private_key->private_key.ecdsa == NULL) { 988233294Sstas hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED, 989233294Sstas "Failed to parse EC private key"); 990233294Sstas return HX509_PARSING_KEY_FAILED; 991233294Sstas } 992233294Sstas private_key->signature_alg = ASN1_OID_ID_ECDSA_WITH_SHA256; 993233294Sstas break; 994233294Sstas 995233294Sstas default: 996233294Sstas return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED; 997233294Sstas } 998233294Sstas 999233294Sstas return 0; 1000233294Sstas} 1001233294Sstas 1002233294Sstasstatic int 1003233294Sstasecdsa_generate_private_key(hx509_context context, 1004233294Sstas struct hx509_generate_private_context *ctx, 1005233294Sstas hx509_private_key private_key) 1006233294Sstas{ 1007233294Sstas return ENOMEM; 1008233294Sstas} 1009233294Sstas 1010233294Sstasstatic BIGNUM * 1011233294Sstasecdsa_get_internal(hx509_context context, 1012233294Sstas hx509_private_key key, 1013233294Sstas const char *type) 1014233294Sstas{ 1015233294Sstas return NULL; 1016233294Sstas} 1017233294Sstas 1018233294Sstas 1019233294Sstasstatic hx509_private_key_ops ecdsa_private_key_ops = { 1020233294Sstas "EC PRIVATE KEY", 1021233294Sstas ASN1_OID_ID_ECPUBLICKEY, 1022233294Sstas ecdsa_available, 1023233294Sstas ecdsa_private_key2SPKI, 1024233294Sstas ecdsa_private_key_export, 1025233294Sstas ecdsa_private_key_import, 1026233294Sstas ecdsa_generate_private_key, 1027233294Sstas ecdsa_get_internal 1028233294Sstas}; 1029233294Sstas 1030233294Sstas#endif /* HAVE_OPENSSL */ 1031233294Sstas 1032178825Sdfr/* 1033178825Sdfr * 1034178825Sdfr */ 1035178825Sdfr 1036178825Sdfrstatic int 1037178825Sdfrdsa_verify_signature(hx509_context context, 1038178825Sdfr const struct signature_alg *sig_alg, 1039178825Sdfr const Certificate *signer, 1040178825Sdfr const AlgorithmIdentifier *alg, 1041178825Sdfr const heim_octet_string *data, 1042178825Sdfr const heim_octet_string *sig) 1043178825Sdfr{ 1044178825Sdfr const SubjectPublicKeyInfo *spi; 1045178825Sdfr DSAPublicKey pk; 1046178825Sdfr DSAParams param; 1047178825Sdfr size_t size; 1048178825Sdfr DSA *dsa; 1049178825Sdfr int ret; 1050178825Sdfr 1051178825Sdfr spi = &signer->tbsCertificate.subjectPublicKeyInfo; 1052178825Sdfr 1053178825Sdfr dsa = DSA_new(); 1054178825Sdfr if (dsa == NULL) { 1055178825Sdfr hx509_set_error_string(context, 0, ENOMEM, "out of memory"); 1056178825Sdfr return ENOMEM; 1057178825Sdfr } 1058178825Sdfr 1059178825Sdfr ret = decode_DSAPublicKey(spi->subjectPublicKey.data, 1060178825Sdfr spi->subjectPublicKey.length / 8, 1061178825Sdfr &pk, &size); 1062178825Sdfr if (ret) 1063178825Sdfr goto out; 1064178825Sdfr 1065178825Sdfr dsa->pub_key = heim_int2BN(&pk); 1066178825Sdfr 1067178825Sdfr free_DSAPublicKey(&pk); 1068178825Sdfr 1069178825Sdfr if (dsa->pub_key == NULL) { 1070178825Sdfr ret = ENOMEM; 1071178825Sdfr hx509_set_error_string(context, 0, ret, "out of memory"); 1072178825Sdfr goto out; 1073178825Sdfr } 1074178825Sdfr 1075178825Sdfr if (spi->algorithm.parameters == NULL) { 1076178825Sdfr ret = HX509_CRYPTO_SIG_INVALID_FORMAT; 1077178825Sdfr hx509_set_error_string(context, 0, ret, "DSA parameters missing"); 1078178825Sdfr goto out; 1079178825Sdfr } 1080178825Sdfr 1081178825Sdfr ret = decode_DSAParams(spi->algorithm.parameters->data, 1082178825Sdfr spi->algorithm.parameters->length, 1083178825Sdfr ¶m, 1084178825Sdfr &size); 1085178825Sdfr if (ret) { 1086178825Sdfr hx509_set_error_string(context, 0, ret, "DSA parameters failed to decode"); 1087178825Sdfr goto out; 1088178825Sdfr } 1089178825Sdfr 1090178825Sdfr dsa->p = heim_int2BN(¶m.p); 1091178825Sdfr dsa->q = heim_int2BN(¶m.q); 1092178825Sdfr dsa->g = heim_int2BN(¶m.g); 1093178825Sdfr 1094178825Sdfr free_DSAParams(¶m); 1095178825Sdfr 1096178825Sdfr if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) { 1097178825Sdfr ret = ENOMEM; 1098178825Sdfr hx509_set_error_string(context, 0, ret, "out of memory"); 1099178825Sdfr goto out; 1100178825Sdfr } 1101178825Sdfr 1102178825Sdfr ret = DSA_verify(-1, data->data, data->length, 1103178825Sdfr (unsigned char*)sig->data, sig->length, 1104178825Sdfr dsa); 1105178825Sdfr if (ret == 1) 1106178825Sdfr ret = 0; 1107178825Sdfr else if (ret == 0 || ret == -1) { 1108178825Sdfr ret = HX509_CRYPTO_BAD_SIGNATURE; 1109178825Sdfr hx509_set_error_string(context, 0, ret, "BAD DSA sigature"); 1110178825Sdfr } else { 1111178825Sdfr ret = HX509_CRYPTO_SIG_INVALID_FORMAT; 1112178825Sdfr hx509_set_error_string(context, 0, ret, "Invalid format of DSA sigature"); 1113178825Sdfr } 1114178825Sdfr 1115178825Sdfr out: 1116178825Sdfr DSA_free(dsa); 1117178825Sdfr 1118178825Sdfr return ret; 1119178825Sdfr} 1120178825Sdfr 1121178825Sdfr#if 0 1122178825Sdfrstatic int 1123178825Sdfrdsa_parse_private_key(hx509_context context, 1124178825Sdfr const void *data, 1125178825Sdfr size_t len, 1126178825Sdfr hx509_private_key private_key) 1127178825Sdfr{ 1128178825Sdfr const unsigned char *p = data; 1129178825Sdfr 1130233294Sstas private_key->private_key.dsa = 1131178825Sdfr d2i_DSAPrivateKey(NULL, &p, len); 1132178825Sdfr if (private_key->private_key.dsa == NULL) 1133178825Sdfr return EINVAL; 1134233294Sstas private_key->signature_alg = ASN1_OID_ID_DSA_WITH_SHA1; 1135178825Sdfr 1136178825Sdfr return 0; 1137178825Sdfr/* else */ 1138178825Sdfr hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED, 1139178825Sdfr "No support to parse DSA keys"); 1140178825Sdfr return HX509_PARSING_KEY_FAILED; 1141178825Sdfr} 1142178825Sdfr#endif 1143178825Sdfr 1144178825Sdfrstatic int 1145233294Sstasevp_md_create_signature(hx509_context context, 1146178825Sdfr const struct signature_alg *sig_alg, 1147178825Sdfr const hx509_private_key signer, 1148178825Sdfr const AlgorithmIdentifier *alg, 1149178825Sdfr const heim_octet_string *data, 1150178825Sdfr AlgorithmIdentifier *signatureAlgorithm, 1151178825Sdfr heim_octet_string *sig) 1152178825Sdfr{ 1153233294Sstas size_t sigsize = EVP_MD_size(sig_alg->evp_md()); 1154233294Sstas EVP_MD_CTX *ctx; 1155233294Sstas 1156178825Sdfr memset(sig, 0, sizeof(*sig)); 1157178825Sdfr 1158178825Sdfr if (signatureAlgorithm) { 1159178825Sdfr int ret; 1160233294Sstas ret = set_digest_alg(signatureAlgorithm, sig_alg->sig_oid, 1161178825Sdfr "\x05\x00", 2); 1162178825Sdfr if (ret) 1163178825Sdfr return ret; 1164178825Sdfr } 1165178825Sdfr 1166233294Sstas 1167233294Sstas sig->data = malloc(sigsize); 1168178825Sdfr if (sig->data == NULL) { 1169178825Sdfr sig->length = 0; 1170178825Sdfr return ENOMEM; 1171178825Sdfr } 1172233294Sstas sig->length = sigsize; 1173178825Sdfr 1174233294Sstas ctx = EVP_MD_CTX_create(); 1175233294Sstas EVP_DigestInit_ex(ctx, sig_alg->evp_md(), NULL); 1176233294Sstas EVP_DigestUpdate(ctx, data->data, data->length); 1177233294Sstas EVP_DigestFinal_ex(ctx, sig->data, NULL); 1178233294Sstas EVP_MD_CTX_destroy(ctx); 1179178825Sdfr 1180233294Sstas 1181178825Sdfr return 0; 1182178825Sdfr} 1183178825Sdfr 1184178825Sdfrstatic int 1185233294Sstasevp_md_verify_signature(hx509_context context, 1186178825Sdfr const struct signature_alg *sig_alg, 1187178825Sdfr const Certificate *signer, 1188178825Sdfr const AlgorithmIdentifier *alg, 1189178825Sdfr const heim_octet_string *data, 1190178825Sdfr const heim_octet_string *sig) 1191178825Sdfr{ 1192233294Sstas unsigned char digest[EVP_MAX_MD_SIZE]; 1193233294Sstas EVP_MD_CTX *ctx; 1194233294Sstas size_t sigsize = EVP_MD_size(sig_alg->evp_md()); 1195233294Sstas 1196233294Sstas if (sig->length != sigsize || sigsize > sizeof(digest)) { 1197178825Sdfr hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT, 1198178825Sdfr "SHA256 sigature have wrong length"); 1199178825Sdfr return HX509_CRYPTO_SIG_INVALID_FORMAT; 1200178825Sdfr } 1201178825Sdfr 1202233294Sstas ctx = EVP_MD_CTX_create(); 1203233294Sstas EVP_DigestInit_ex(ctx, sig_alg->evp_md(), NULL); 1204233294Sstas EVP_DigestUpdate(ctx, data->data, data->length); 1205233294Sstas EVP_DigestFinal_ex(ctx, digest, NULL); 1206233294Sstas EVP_MD_CTX_destroy(ctx); 1207233294Sstas 1208233294Sstas if (ct_memcmp(digest, sig->data, sigsize) != 0) { 1209178825Sdfr hx509_set_error_string(context, 0, HX509_CRYPTO_BAD_SIGNATURE, 1210233294Sstas "Bad %s sigature", sig_alg->name); 1211178825Sdfr return HX509_CRYPTO_BAD_SIGNATURE; 1212178825Sdfr } 1213178825Sdfr 1214178825Sdfr return 0; 1215178825Sdfr} 1216178825Sdfr 1217233294Sstas#ifdef HAVE_OPENSSL 1218178825Sdfr 1219233294Sstasstatic const struct signature_alg ecdsa_with_sha256_alg = { 1220233294Sstas "ecdsa-with-sha256", 1221233294Sstas ASN1_OID_ID_ECDSA_WITH_SHA256, 1222233294Sstas &_hx509_signature_ecdsa_with_sha256_data, 1223233294Sstas ASN1_OID_ID_ECPUBLICKEY, 1224233294Sstas &_hx509_signature_sha256_data, 1225233294Sstas PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK, 1226233294Sstas 0, 1227233294Sstas NULL, 1228233294Sstas ecdsa_verify_signature, 1229233294Sstas ecdsa_create_signature, 1230233294Sstas 32 1231233294Sstas}; 1232178825Sdfr 1233233294Sstasstatic const struct signature_alg ecdsa_with_sha1_alg = { 1234233294Sstas "ecdsa-with-sha1", 1235233294Sstas ASN1_OID_ID_ECDSA_WITH_SHA1, 1236233294Sstas &_hx509_signature_ecdsa_with_sha1_data, 1237233294Sstas ASN1_OID_ID_ECPUBLICKEY, 1238233294Sstas &_hx509_signature_sha1_data, 1239233294Sstas PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK, 1240233294Sstas 0, 1241233294Sstas NULL, 1242233294Sstas ecdsa_verify_signature, 1243233294Sstas ecdsa_create_signature, 1244233294Sstas 20 1245233294Sstas}; 1246178825Sdfr 1247233294Sstas#endif 1248178825Sdfr 1249178825Sdfrstatic const struct signature_alg heim_rsa_pkcs1_x509 = { 1250178825Sdfr "rsa-pkcs1-x509", 1251233294Sstas ASN1_OID_ID_HEIM_RSA_PKCS1_X509, 1252233294Sstas &_hx509_signature_rsa_pkcs1_x509_data, 1253233294Sstas ASN1_OID_ID_PKCS1_RSAENCRYPTION, 1254178825Sdfr NULL, 1255178825Sdfr PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG, 1256233294Sstas 0, 1257233294Sstas NULL, 1258178825Sdfr rsa_verify_signature, 1259233294Sstas rsa_create_signature, 1260233294Sstas 0 1261178825Sdfr}; 1262178825Sdfr 1263178825Sdfrstatic const struct signature_alg pkcs1_rsa_sha1_alg = { 1264178825Sdfr "rsa", 1265233294Sstas ASN1_OID_ID_PKCS1_RSAENCRYPTION, 1266233294Sstas &_hx509_signature_rsa_with_sha1_data, 1267233294Sstas ASN1_OID_ID_PKCS1_RSAENCRYPTION, 1268178825Sdfr NULL, 1269233294Sstas PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK, 1270233294Sstas 0, 1271233294Sstas NULL, 1272178825Sdfr rsa_verify_signature, 1273233294Sstas rsa_create_signature, 1274233294Sstas 0 1275178825Sdfr}; 1276178825Sdfr 1277233294Sstasstatic const struct signature_alg rsa_with_sha512_alg = { 1278233294Sstas "rsa-with-sha512", 1279233294Sstas ASN1_OID_ID_PKCS1_SHA512WITHRSAENCRYPTION, 1280233294Sstas &_hx509_signature_rsa_with_sha512_data, 1281233294Sstas ASN1_OID_ID_PKCS1_RSAENCRYPTION, 1282233294Sstas &_hx509_signature_sha512_data, 1283233294Sstas PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK, 1284233294Sstas 0, 1285233294Sstas NULL, 1286233294Sstas rsa_verify_signature, 1287233294Sstas rsa_create_signature, 1288233294Sstas 0 1289233294Sstas}; 1290233294Sstas 1291233294Sstasstatic const struct signature_alg rsa_with_sha384_alg = { 1292233294Sstas "rsa-with-sha384", 1293233294Sstas ASN1_OID_ID_PKCS1_SHA384WITHRSAENCRYPTION, 1294233294Sstas &_hx509_signature_rsa_with_sha384_data, 1295233294Sstas ASN1_OID_ID_PKCS1_RSAENCRYPTION, 1296233294Sstas &_hx509_signature_sha384_data, 1297233294Sstas PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK, 1298233294Sstas 0, 1299233294Sstas NULL, 1300233294Sstas rsa_verify_signature, 1301233294Sstas rsa_create_signature, 1302233294Sstas 0 1303233294Sstas}; 1304233294Sstas 1305178825Sdfrstatic const struct signature_alg rsa_with_sha256_alg = { 1306178825Sdfr "rsa-with-sha256", 1307233294Sstas ASN1_OID_ID_PKCS1_SHA256WITHRSAENCRYPTION, 1308233294Sstas &_hx509_signature_rsa_with_sha256_data, 1309233294Sstas ASN1_OID_ID_PKCS1_RSAENCRYPTION, 1310233294Sstas &_hx509_signature_sha256_data, 1311233294Sstas PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK, 1312233294Sstas 0, 1313233294Sstas NULL, 1314178825Sdfr rsa_verify_signature, 1315233294Sstas rsa_create_signature, 1316233294Sstas 0 1317178825Sdfr}; 1318178825Sdfr 1319178825Sdfrstatic const struct signature_alg rsa_with_sha1_alg = { 1320178825Sdfr "rsa-with-sha1", 1321233294Sstas ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION, 1322233294Sstas &_hx509_signature_rsa_with_sha1_data, 1323233294Sstas ASN1_OID_ID_PKCS1_RSAENCRYPTION, 1324233294Sstas &_hx509_signature_sha1_data, 1325233294Sstas PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK, 1326233294Sstas 0, 1327233294Sstas NULL, 1328178825Sdfr rsa_verify_signature, 1329233294Sstas rsa_create_signature, 1330233294Sstas 0 1331178825Sdfr}; 1332178825Sdfr 1333233294Sstasstatic const struct signature_alg rsa_with_sha1_alg_secsig = { 1334233294Sstas "rsa-with-sha1", 1335233294Sstas ASN1_OID_ID_SECSIG_SHA_1WITHRSAENCRYPTION, 1336233294Sstas &_hx509_signature_rsa_with_sha1_data, 1337233294Sstas ASN1_OID_ID_PKCS1_RSAENCRYPTION, 1338233294Sstas &_hx509_signature_sha1_data, 1339233294Sstas PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK, 1340233294Sstas 0, 1341233294Sstas NULL, 1342178825Sdfr rsa_verify_signature, 1343233294Sstas rsa_create_signature, 1344233294Sstas 0 1345178825Sdfr}; 1346178825Sdfr 1347233294Sstasstatic const struct signature_alg rsa_with_md5_alg = { 1348233294Sstas "rsa-with-md5", 1349233294Sstas ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION, 1350233294Sstas &_hx509_signature_rsa_with_md5_data, 1351233294Sstas ASN1_OID_ID_PKCS1_RSAENCRYPTION, 1352233294Sstas &_hx509_signature_md5_data, 1353178825Sdfr PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG, 1354233294Sstas 1230739889, 1355233294Sstas NULL, 1356178825Sdfr rsa_verify_signature, 1357233294Sstas rsa_create_signature, 1358233294Sstas 0 1359178825Sdfr}; 1360178825Sdfr 1361178825Sdfrstatic const struct signature_alg dsa_sha1_alg = { 1362178825Sdfr "dsa-with-sha1", 1363233294Sstas ASN1_OID_ID_DSA_WITH_SHA1, 1364178825Sdfr NULL, 1365233294Sstas ASN1_OID_ID_DSA, 1366233294Sstas &_hx509_signature_sha1_data, 1367178825Sdfr PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG, 1368233294Sstas 0, 1369233294Sstas NULL, 1370178825Sdfr dsa_verify_signature, 1371178825Sdfr /* create_signature */ NULL, 1372233294Sstas 0 1373178825Sdfr}; 1374178825Sdfr 1375233294Sstasstatic const struct signature_alg sha512_alg = { 1376233294Sstas "sha-512", 1377233294Sstas ASN1_OID_ID_SHA512, 1378233294Sstas &_hx509_signature_sha512_data, 1379233294Sstas NULL, 1380233294Sstas NULL, 1381233294Sstas SIG_DIGEST, 1382233294Sstas 0, 1383233294Sstas EVP_sha512, 1384233294Sstas evp_md_verify_signature, 1385233294Sstas evp_md_create_signature, 1386233294Sstas 0 1387233294Sstas}; 1388233294Sstas 1389233294Sstasstatic const struct signature_alg sha384_alg = { 1390233294Sstas "sha-384", 1391233294Sstas ASN1_OID_ID_SHA512, 1392233294Sstas &_hx509_signature_sha384_data, 1393233294Sstas NULL, 1394233294Sstas NULL, 1395233294Sstas SIG_DIGEST, 1396233294Sstas 0, 1397233294Sstas EVP_sha384, 1398233294Sstas evp_md_verify_signature, 1399233294Sstas evp_md_create_signature, 1400233294Sstas 0 1401233294Sstas}; 1402233294Sstas 1403178825Sdfrstatic const struct signature_alg sha256_alg = { 1404178825Sdfr "sha-256", 1405233294Sstas ASN1_OID_ID_SHA256, 1406233294Sstas &_hx509_signature_sha256_data, 1407178825Sdfr NULL, 1408178825Sdfr NULL, 1409178825Sdfr SIG_DIGEST, 1410233294Sstas 0, 1411233294Sstas EVP_sha256, 1412233294Sstas evp_md_verify_signature, 1413233294Sstas evp_md_create_signature, 1414233294Sstas 0 1415178825Sdfr}; 1416178825Sdfr 1417178825Sdfrstatic const struct signature_alg sha1_alg = { 1418178825Sdfr "sha1", 1419233294Sstas ASN1_OID_ID_SECSIG_SHA_1, 1420233294Sstas &_hx509_signature_sha1_data, 1421178825Sdfr NULL, 1422178825Sdfr NULL, 1423178825Sdfr SIG_DIGEST, 1424233294Sstas 0, 1425233294Sstas EVP_sha1, 1426233294Sstas evp_md_verify_signature, 1427233294Sstas evp_md_create_signature, 1428233294Sstas 0 1429178825Sdfr}; 1430178825Sdfr 1431178825Sdfrstatic const struct signature_alg md5_alg = { 1432178825Sdfr "rsa-md5", 1433233294Sstas ASN1_OID_ID_RSA_DIGEST_MD5, 1434233294Sstas &_hx509_signature_md5_data, 1435178825Sdfr NULL, 1436178825Sdfr NULL, 1437178825Sdfr SIG_DIGEST, 1438233294Sstas 0, 1439233294Sstas EVP_md5, 1440233294Sstas evp_md_verify_signature, 1441178825Sdfr NULL, 1442233294Sstas 0 1443178825Sdfr}; 1444178825Sdfr 1445233294Sstas/* 1446178825Sdfr * Order matter in this structure, "best" first for each "key 1447233294Sstas * compatible" type (type is ECDSA, RSA, DSA, none, etc) 1448178825Sdfr */ 1449178825Sdfr 1450178825Sdfrstatic const struct signature_alg *sig_algs[] = { 1451233294Sstas#ifdef HAVE_OPENSSL 1452233294Sstas &ecdsa_with_sha256_alg, 1453233294Sstas &ecdsa_with_sha1_alg, 1454233294Sstas#endif 1455233294Sstas &rsa_with_sha512_alg, 1456233294Sstas &rsa_with_sha384_alg, 1457178825Sdfr &rsa_with_sha256_alg, 1458178825Sdfr &rsa_with_sha1_alg, 1459233294Sstas &rsa_with_sha1_alg_secsig, 1460178825Sdfr &pkcs1_rsa_sha1_alg, 1461178825Sdfr &rsa_with_md5_alg, 1462178825Sdfr &heim_rsa_pkcs1_x509, 1463178825Sdfr &dsa_sha1_alg, 1464233294Sstas &sha512_alg, 1465233294Sstas &sha384_alg, 1466178825Sdfr &sha256_alg, 1467178825Sdfr &sha1_alg, 1468178825Sdfr &md5_alg, 1469178825Sdfr NULL 1470178825Sdfr}; 1471178825Sdfr 1472178825Sdfrstatic const struct signature_alg * 1473178825Sdfrfind_sig_alg(const heim_oid *oid) 1474178825Sdfr{ 1475233294Sstas unsigned int i; 1476178825Sdfr for (i = 0; sig_algs[i]; i++) 1477233294Sstas if (der_heim_oid_cmp(sig_algs[i]->sig_oid, oid) == 0) 1478178825Sdfr return sig_algs[i]; 1479178825Sdfr return NULL; 1480178825Sdfr} 1481178825Sdfr 1482233294Sstasstatic const AlgorithmIdentifier * 1483233294Sstasalg_for_privatekey(const hx509_private_key pk, int type) 1484233294Sstas{ 1485233294Sstas const heim_oid *keytype; 1486233294Sstas unsigned int i; 1487233294Sstas 1488233294Sstas if (pk->ops == NULL) 1489233294Sstas return NULL; 1490233294Sstas 1491233294Sstas keytype = pk->ops->key_oid; 1492233294Sstas 1493233294Sstas for (i = 0; sig_algs[i]; i++) { 1494233294Sstas if (sig_algs[i]->key_oid == NULL) 1495233294Sstas continue; 1496233294Sstas if (der_heim_oid_cmp(sig_algs[i]->key_oid, keytype) != 0) 1497233294Sstas continue; 1498233294Sstas if (pk->ops->available && 1499233294Sstas pk->ops->available(pk, sig_algs[i]->sig_alg) == 0) 1500233294Sstas continue; 1501233294Sstas if (type == HX509_SELECT_PUBLIC_SIG) 1502233294Sstas return sig_algs[i]->sig_alg; 1503233294Sstas if (type == HX509_SELECT_DIGEST) 1504233294Sstas return sig_algs[i]->digest_alg; 1505233294Sstas 1506233294Sstas return NULL; 1507233294Sstas } 1508233294Sstas return NULL; 1509233294Sstas} 1510233294Sstas 1511178825Sdfr/* 1512178825Sdfr * 1513178825Sdfr */ 1514178825Sdfr 1515178825Sdfrstatic struct hx509_private_key_ops *private_algs[] = { 1516178825Sdfr &rsa_private_key_ops, 1517233294Sstas#ifdef HAVE_OPENSSL 1518233294Sstas &ecdsa_private_key_ops, 1519233294Sstas#endif 1520178825Sdfr NULL 1521178825Sdfr}; 1522178825Sdfr 1523233294Sstashx509_private_key_ops * 1524233294Sstashx509_find_private_alg(const heim_oid *oid) 1525178825Sdfr{ 1526178825Sdfr int i; 1527178825Sdfr for (i = 0; private_algs[i]; i++) { 1528178825Sdfr if (private_algs[i]->key_oid == NULL) 1529178825Sdfr continue; 1530233294Sstas if (der_heim_oid_cmp(private_algs[i]->key_oid, oid) == 0) 1531178825Sdfr return private_algs[i]; 1532178825Sdfr } 1533178825Sdfr return NULL; 1534178825Sdfr} 1535178825Sdfr 1536233294Sstas/* 1537233294Sstas * Check if the algorithm `alg' have a best before date, and if it 1538233294Sstas * des, make sure the its before the time `t'. 1539233294Sstas */ 1540178825Sdfr 1541178825Sdfrint 1542233294Sstas_hx509_signature_best_before(hx509_context context, 1543233294Sstas const AlgorithmIdentifier *alg, 1544233294Sstas time_t t) 1545233294Sstas{ 1546233294Sstas const struct signature_alg *md; 1547233294Sstas 1548233294Sstas md = find_sig_alg(&alg->algorithm); 1549233294Sstas if (md == NULL) { 1550233294Sstas hx509_clear_error_string(context); 1551233294Sstas return HX509_SIG_ALG_NO_SUPPORTED; 1552233294Sstas } 1553233294Sstas if (md->best_before && md->best_before < t) { 1554233294Sstas hx509_set_error_string(context, 0, HX509_CRYPTO_ALGORITHM_BEST_BEFORE, 1555233294Sstas "Algorithm %s has passed it best before date", 1556233294Sstas md->name); 1557233294Sstas return HX509_CRYPTO_ALGORITHM_BEST_BEFORE; 1558233294Sstas } 1559233294Sstas return 0; 1560233294Sstas} 1561233294Sstas 1562233294Sstasint 1563233294Sstas_hx509_self_signed_valid(hx509_context context, 1564233294Sstas const AlgorithmIdentifier *alg) 1565233294Sstas{ 1566233294Sstas const struct signature_alg *md; 1567233294Sstas 1568233294Sstas md = find_sig_alg(&alg->algorithm); 1569233294Sstas if (md == NULL) { 1570233294Sstas hx509_clear_error_string(context); 1571233294Sstas return HX509_SIG_ALG_NO_SUPPORTED; 1572233294Sstas } 1573233294Sstas if ((md->flags & SELF_SIGNED_OK) == 0) { 1574233294Sstas hx509_set_error_string(context, 0, HX509_CRYPTO_ALGORITHM_BEST_BEFORE, 1575233294Sstas "Algorithm %s not trusted for self signatures", 1576233294Sstas md->name); 1577233294Sstas return HX509_CRYPTO_ALGORITHM_BEST_BEFORE; 1578233294Sstas } 1579233294Sstas return 0; 1580233294Sstas} 1581233294Sstas 1582233294Sstas 1583233294Sstasint 1584178825Sdfr_hx509_verify_signature(hx509_context context, 1585233294Sstas const hx509_cert cert, 1586178825Sdfr const AlgorithmIdentifier *alg, 1587178825Sdfr const heim_octet_string *data, 1588178825Sdfr const heim_octet_string *sig) 1589178825Sdfr{ 1590178825Sdfr const struct signature_alg *md; 1591233294Sstas const Certificate *signer = NULL; 1592178825Sdfr 1593233294Sstas if (cert) 1594233294Sstas signer = _hx509_get_cert(cert); 1595233294Sstas 1596178825Sdfr md = find_sig_alg(&alg->algorithm); 1597178825Sdfr if (md == NULL) { 1598178825Sdfr hx509_clear_error_string(context); 1599178825Sdfr return HX509_SIG_ALG_NO_SUPPORTED; 1600178825Sdfr } 1601178825Sdfr if (signer && (md->flags & PROVIDE_CONF) == 0) { 1602178825Sdfr hx509_clear_error_string(context); 1603178825Sdfr return HX509_CRYPTO_SIG_NO_CONF; 1604178825Sdfr } 1605178825Sdfr if (signer == NULL && (md->flags & REQUIRE_SIGNER)) { 1606178825Sdfr hx509_clear_error_string(context); 1607178825Sdfr return HX509_CRYPTO_SIGNATURE_WITHOUT_SIGNER; 1608178825Sdfr } 1609178825Sdfr if (md->key_oid && signer) { 1610178825Sdfr const SubjectPublicKeyInfo *spi; 1611178825Sdfr spi = &signer->tbsCertificate.subjectPublicKeyInfo; 1612178825Sdfr 1613233294Sstas if (der_heim_oid_cmp(&spi->algorithm.algorithm, md->key_oid) != 0) { 1614178825Sdfr hx509_clear_error_string(context); 1615178825Sdfr return HX509_SIG_ALG_DONT_MATCH_KEY_ALG; 1616178825Sdfr } 1617178825Sdfr } 1618178825Sdfr return (*md->verify_signature)(context, md, signer, alg, data, sig); 1619178825Sdfr} 1620178825Sdfr 1621178825Sdfrint 1622178825Sdfr_hx509_create_signature(hx509_context context, 1623178825Sdfr const hx509_private_key signer, 1624178825Sdfr const AlgorithmIdentifier *alg, 1625178825Sdfr const heim_octet_string *data, 1626178825Sdfr AlgorithmIdentifier *signatureAlgorithm, 1627178825Sdfr heim_octet_string *sig) 1628178825Sdfr{ 1629178825Sdfr const struct signature_alg *md; 1630178825Sdfr 1631178825Sdfr md = find_sig_alg(&alg->algorithm); 1632178825Sdfr if (md == NULL) { 1633178825Sdfr hx509_set_error_string(context, 0, HX509_SIG_ALG_NO_SUPPORTED, 1634178825Sdfr "algorithm no supported"); 1635178825Sdfr return HX509_SIG_ALG_NO_SUPPORTED; 1636178825Sdfr } 1637178825Sdfr 1638178825Sdfr if (signer && (md->flags & PROVIDE_CONF) == 0) { 1639178825Sdfr hx509_set_error_string(context, 0, HX509_SIG_ALG_NO_SUPPORTED, 1640178825Sdfr "algorithm provides no conf"); 1641178825Sdfr return HX509_CRYPTO_SIG_NO_CONF; 1642178825Sdfr } 1643178825Sdfr 1644233294Sstas return (*md->create_signature)(context, md, signer, alg, data, 1645178825Sdfr signatureAlgorithm, sig); 1646178825Sdfr} 1647178825Sdfr 1648178825Sdfrint 1649178825Sdfr_hx509_create_signature_bitstring(hx509_context context, 1650178825Sdfr const hx509_private_key signer, 1651178825Sdfr const AlgorithmIdentifier *alg, 1652178825Sdfr const heim_octet_string *data, 1653178825Sdfr AlgorithmIdentifier *signatureAlgorithm, 1654178825Sdfr heim_bit_string *sig) 1655178825Sdfr{ 1656178825Sdfr heim_octet_string os; 1657178825Sdfr int ret; 1658178825Sdfr 1659178825Sdfr ret = _hx509_create_signature(context, signer, alg, 1660178825Sdfr data, signatureAlgorithm, &os); 1661178825Sdfr if (ret) 1662178825Sdfr return ret; 1663178825Sdfr sig->data = os.data; 1664178825Sdfr sig->length = os.length * 8; 1665178825Sdfr return 0; 1666178825Sdfr} 1667178825Sdfr 1668178825Sdfrint 1669178825Sdfr_hx509_public_encrypt(hx509_context context, 1670178825Sdfr const heim_octet_string *cleartext, 1671178825Sdfr const Certificate *cert, 1672178825Sdfr heim_oid *encryption_oid, 1673178825Sdfr heim_octet_string *ciphertext) 1674178825Sdfr{ 1675178825Sdfr const SubjectPublicKeyInfo *spi; 1676178825Sdfr unsigned char *to; 1677178825Sdfr int tosize; 1678178825Sdfr int ret; 1679178825Sdfr RSA *rsa; 1680178825Sdfr size_t size; 1681233294Sstas const unsigned char *p; 1682178825Sdfr 1683178825Sdfr ciphertext->data = NULL; 1684178825Sdfr ciphertext->length = 0; 1685178825Sdfr 1686178825Sdfr spi = &cert->tbsCertificate.subjectPublicKeyInfo; 1687178825Sdfr 1688233294Sstas p = spi->subjectPublicKey.data; 1689233294Sstas size = spi->subjectPublicKey.length / 8; 1690233294Sstas 1691233294Sstas rsa = d2i_RSAPublicKey(NULL, &p, size); 1692178825Sdfr if (rsa == NULL) { 1693178825Sdfr hx509_set_error_string(context, 0, ENOMEM, "out of memory"); 1694178825Sdfr return ENOMEM; 1695178825Sdfr } 1696178825Sdfr 1697178825Sdfr tosize = RSA_size(rsa); 1698178825Sdfr to = malloc(tosize); 1699178825Sdfr if (to == NULL) { 1700178825Sdfr RSA_free(rsa); 1701178825Sdfr hx509_set_error_string(context, 0, ENOMEM, "out of memory"); 1702178825Sdfr return ENOMEM; 1703178825Sdfr } 1704178825Sdfr 1705233294Sstas ret = RSA_public_encrypt(cleartext->length, 1706233294Sstas (unsigned char *)cleartext->data, 1707178825Sdfr to, rsa, RSA_PKCS1_PADDING); 1708178825Sdfr RSA_free(rsa); 1709178825Sdfr if (ret <= 0) { 1710178825Sdfr free(to); 1711178825Sdfr hx509_set_error_string(context, 0, HX509_CRYPTO_RSA_PUBLIC_ENCRYPT, 1712178825Sdfr "RSA public encrypt failed with %d", ret); 1713178825Sdfr return HX509_CRYPTO_RSA_PUBLIC_ENCRYPT; 1714178825Sdfr } 1715178825Sdfr if (ret > tosize) 1716178825Sdfr _hx509_abort("internal rsa decryption failure: ret > tosize"); 1717178825Sdfr 1718178825Sdfr ciphertext->length = ret; 1719178825Sdfr ciphertext->data = to; 1720178825Sdfr 1721233294Sstas ret = der_copy_oid(ASN1_OID_ID_PKCS1_RSAENCRYPTION, encryption_oid); 1722178825Sdfr if (ret) { 1723178825Sdfr der_free_octet_string(ciphertext); 1724178825Sdfr hx509_set_error_string(context, 0, ENOMEM, "out of memory"); 1725178825Sdfr return ENOMEM; 1726178825Sdfr } 1727178825Sdfr 1728178825Sdfr return 0; 1729178825Sdfr} 1730178825Sdfr 1731178825Sdfrint 1732233294Sstashx509_private_key_private_decrypt(hx509_context context, 1733178825Sdfr const heim_octet_string *ciphertext, 1734178825Sdfr const heim_oid *encryption_oid, 1735178825Sdfr hx509_private_key p, 1736178825Sdfr heim_octet_string *cleartext) 1737178825Sdfr{ 1738178825Sdfr int ret; 1739178825Sdfr 1740178825Sdfr cleartext->data = NULL; 1741178825Sdfr cleartext->length = 0; 1742178825Sdfr 1743178825Sdfr if (p->private_key.rsa == NULL) { 1744178825Sdfr hx509_set_error_string(context, 0, HX509_PRIVATE_KEY_MISSING, 1745178825Sdfr "Private RSA key missing"); 1746178825Sdfr return HX509_PRIVATE_KEY_MISSING; 1747178825Sdfr } 1748178825Sdfr 1749178825Sdfr cleartext->length = RSA_size(p->private_key.rsa); 1750178825Sdfr cleartext->data = malloc(cleartext->length); 1751178825Sdfr if (cleartext->data == NULL) { 1752178825Sdfr hx509_set_error_string(context, 0, ENOMEM, "out of memory"); 1753178825Sdfr return ENOMEM; 1754178825Sdfr } 1755178825Sdfr ret = RSA_private_decrypt(ciphertext->length, ciphertext->data, 1756178825Sdfr cleartext->data, 1757178825Sdfr p->private_key.rsa, 1758178825Sdfr RSA_PKCS1_PADDING); 1759178825Sdfr if (ret <= 0) { 1760178825Sdfr der_free_octet_string(cleartext); 1761178825Sdfr hx509_set_error_string(context, 0, HX509_CRYPTO_RSA_PRIVATE_DECRYPT, 1762178825Sdfr "Failed to decrypt using private key: %d", ret); 1763178825Sdfr return HX509_CRYPTO_RSA_PRIVATE_DECRYPT; 1764178825Sdfr } 1765233294Sstas if (cleartext->length < (size_t)ret) 1766178825Sdfr _hx509_abort("internal rsa decryption failure: ret > tosize"); 1767178825Sdfr 1768178825Sdfr cleartext->length = ret; 1769178825Sdfr 1770178825Sdfr return 0; 1771178825Sdfr} 1772178825Sdfr 1773178825Sdfr 1774178825Sdfrint 1775233294Sstashx509_parse_private_key(hx509_context context, 1776233294Sstas const AlgorithmIdentifier *keyai, 1777178825Sdfr const void *data, 1778178825Sdfr size_t len, 1779233294Sstas hx509_key_format_t format, 1780178825Sdfr hx509_private_key *private_key) 1781178825Sdfr{ 1782178825Sdfr struct hx509_private_key_ops *ops; 1783178825Sdfr int ret; 1784178825Sdfr 1785178825Sdfr *private_key = NULL; 1786178825Sdfr 1787233294Sstas ops = hx509_find_private_alg(&keyai->algorithm); 1788178825Sdfr if (ops == NULL) { 1789178825Sdfr hx509_clear_error_string(context); 1790178825Sdfr return HX509_SIG_ALG_NO_SUPPORTED; 1791178825Sdfr } 1792178825Sdfr 1793233294Sstas ret = hx509_private_key_init(private_key, ops, NULL); 1794178825Sdfr if (ret) { 1795178825Sdfr hx509_set_error_string(context, 0, ret, "out of memory"); 1796178825Sdfr return ret; 1797178825Sdfr } 1798178825Sdfr 1799233294Sstas ret = (*ops->import)(context, keyai, data, len, format, *private_key); 1800178825Sdfr if (ret) 1801233294Sstas hx509_private_key_free(private_key); 1802178825Sdfr 1803178825Sdfr return ret; 1804178825Sdfr} 1805178825Sdfr 1806178825Sdfr/* 1807178825Sdfr * 1808178825Sdfr */ 1809178825Sdfr 1810178825Sdfrint 1811233294Sstashx509_private_key2SPKI(hx509_context context, 1812178825Sdfr hx509_private_key private_key, 1813178825Sdfr SubjectPublicKeyInfo *spki) 1814178825Sdfr{ 1815178825Sdfr const struct hx509_private_key_ops *ops = private_key->ops; 1816178825Sdfr if (ops == NULL || ops->get_spki == NULL) { 1817178825Sdfr hx509_set_error_string(context, 0, HX509_UNIMPLEMENTED_OPERATION, 1818178825Sdfr "Private key have no key2SPKI function"); 1819178825Sdfr return HX509_UNIMPLEMENTED_OPERATION; 1820178825Sdfr } 1821178825Sdfr return (*ops->get_spki)(context, private_key, spki); 1822178825Sdfr} 1823178825Sdfr 1824178825Sdfrint 1825178825Sdfr_hx509_generate_private_key_init(hx509_context context, 1826178825Sdfr const heim_oid *oid, 1827178825Sdfr struct hx509_generate_private_context **ctx) 1828178825Sdfr{ 1829178825Sdfr *ctx = NULL; 1830178825Sdfr 1831233294Sstas if (der_heim_oid_cmp(oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) != 0) { 1832233294Sstas hx509_set_error_string(context, 0, EINVAL, 1833178825Sdfr "private key not an RSA key"); 1834178825Sdfr return EINVAL; 1835178825Sdfr } 1836178825Sdfr 1837178825Sdfr *ctx = calloc(1, sizeof(**ctx)); 1838178825Sdfr if (*ctx == NULL) { 1839178825Sdfr hx509_set_error_string(context, 0, ENOMEM, "out of memory"); 1840178825Sdfr return ENOMEM; 1841178825Sdfr } 1842178825Sdfr (*ctx)->key_oid = oid; 1843178825Sdfr 1844178825Sdfr return 0; 1845178825Sdfr} 1846178825Sdfr 1847178825Sdfrint 1848178825Sdfr_hx509_generate_private_key_is_ca(hx509_context context, 1849178825Sdfr struct hx509_generate_private_context *ctx) 1850178825Sdfr{ 1851178825Sdfr ctx->isCA = 1; 1852178825Sdfr return 0; 1853178825Sdfr} 1854178825Sdfr 1855178825Sdfrint 1856178825Sdfr_hx509_generate_private_key_bits(hx509_context context, 1857178825Sdfr struct hx509_generate_private_context *ctx, 1858178825Sdfr unsigned long bits) 1859178825Sdfr{ 1860178825Sdfr ctx->num_bits = bits; 1861178825Sdfr return 0; 1862178825Sdfr} 1863178825Sdfr 1864178825Sdfr 1865178825Sdfrvoid 1866178825Sdfr_hx509_generate_private_key_free(struct hx509_generate_private_context **ctx) 1867178825Sdfr{ 1868178825Sdfr free(*ctx); 1869178825Sdfr *ctx = NULL; 1870178825Sdfr} 1871178825Sdfr 1872178825Sdfrint 1873178825Sdfr_hx509_generate_private_key(hx509_context context, 1874178825Sdfr struct hx509_generate_private_context *ctx, 1875178825Sdfr hx509_private_key *private_key) 1876178825Sdfr{ 1877178825Sdfr struct hx509_private_key_ops *ops; 1878178825Sdfr int ret; 1879178825Sdfr 1880178825Sdfr *private_key = NULL; 1881178825Sdfr 1882233294Sstas ops = hx509_find_private_alg(ctx->key_oid); 1883178825Sdfr if (ops == NULL) { 1884178825Sdfr hx509_clear_error_string(context); 1885178825Sdfr return HX509_SIG_ALG_NO_SUPPORTED; 1886178825Sdfr } 1887178825Sdfr 1888233294Sstas ret = hx509_private_key_init(private_key, ops, NULL); 1889178825Sdfr if (ret) { 1890178825Sdfr hx509_set_error_string(context, 0, ret, "out of memory"); 1891178825Sdfr return ret; 1892178825Sdfr } 1893178825Sdfr 1894178825Sdfr ret = (*ops->generate_private_key)(context, ctx, *private_key); 1895178825Sdfr if (ret) 1896233294Sstas hx509_private_key_free(private_key); 1897178825Sdfr 1898178825Sdfr return ret; 1899178825Sdfr} 1900178825Sdfr 1901178825Sdfr/* 1902178825Sdfr * 1903178825Sdfr */ 1904178825Sdfr 1905178825Sdfrconst AlgorithmIdentifier * 1906178825Sdfrhx509_signature_sha512(void) 1907178825Sdfr{ return &_hx509_signature_sha512_data; } 1908178825Sdfr 1909178825Sdfrconst AlgorithmIdentifier * 1910178825Sdfrhx509_signature_sha384(void) 1911178825Sdfr{ return &_hx509_signature_sha384_data; } 1912178825Sdfr 1913178825Sdfrconst AlgorithmIdentifier * 1914178825Sdfrhx509_signature_sha256(void) 1915178825Sdfr{ return &_hx509_signature_sha256_data; } 1916178825Sdfr 1917178825Sdfrconst AlgorithmIdentifier * 1918178825Sdfrhx509_signature_sha1(void) 1919178825Sdfr{ return &_hx509_signature_sha1_data; } 1920178825Sdfr 1921178825Sdfrconst AlgorithmIdentifier * 1922178825Sdfrhx509_signature_md5(void) 1923178825Sdfr{ return &_hx509_signature_md5_data; } 1924178825Sdfr 1925178825Sdfrconst AlgorithmIdentifier * 1926233294Sstashx509_signature_ecPublicKey(void) 1927233294Sstas{ return &_hx509_signature_ecPublicKey; } 1928178825Sdfr 1929178825Sdfrconst AlgorithmIdentifier * 1930233294Sstashx509_signature_ecdsa_with_sha256(void) 1931233294Sstas{ return &_hx509_signature_ecdsa_with_sha256_data; } 1932233294Sstas 1933233294Sstasconst AlgorithmIdentifier * 1934233294Sstashx509_signature_ecdsa_with_sha1(void) 1935233294Sstas{ return &_hx509_signature_ecdsa_with_sha1_data; } 1936233294Sstas 1937233294Sstasconst AlgorithmIdentifier * 1938178825Sdfrhx509_signature_rsa_with_sha512(void) 1939178825Sdfr{ return &_hx509_signature_rsa_with_sha512_data; } 1940178825Sdfr 1941178825Sdfrconst AlgorithmIdentifier * 1942178825Sdfrhx509_signature_rsa_with_sha384(void) 1943178825Sdfr{ return &_hx509_signature_rsa_with_sha384_data; } 1944178825Sdfr 1945178825Sdfrconst AlgorithmIdentifier * 1946178825Sdfrhx509_signature_rsa_with_sha256(void) 1947178825Sdfr{ return &_hx509_signature_rsa_with_sha256_data; } 1948178825Sdfr 1949178825Sdfrconst AlgorithmIdentifier * 1950178825Sdfrhx509_signature_rsa_with_sha1(void) 1951178825Sdfr{ return &_hx509_signature_rsa_with_sha1_data; } 1952178825Sdfr 1953178825Sdfrconst AlgorithmIdentifier * 1954178825Sdfrhx509_signature_rsa_with_md5(void) 1955178825Sdfr{ return &_hx509_signature_rsa_with_md5_data; } 1956178825Sdfr 1957178825Sdfrconst AlgorithmIdentifier * 1958178825Sdfrhx509_signature_rsa(void) 1959178825Sdfr{ return &_hx509_signature_rsa_data; } 1960178825Sdfr 1961178825Sdfrconst AlgorithmIdentifier * 1962178825Sdfrhx509_signature_rsa_pkcs1_x509(void) 1963178825Sdfr{ return &_hx509_signature_rsa_pkcs1_x509_data; } 1964178825Sdfr 1965178825Sdfrconst AlgorithmIdentifier * 1966178825Sdfrhx509_crypto_des_rsdi_ede3_cbc(void) 1967178825Sdfr{ return &_hx509_des_rsdi_ede3_cbc_oid; } 1968178825Sdfr 1969178825Sdfrconst AlgorithmIdentifier * 1970178825Sdfrhx509_crypto_aes128_cbc(void) 1971178825Sdfr{ return &_hx509_crypto_aes128_cbc_data; } 1972178825Sdfr 1973178825Sdfrconst AlgorithmIdentifier * 1974178825Sdfrhx509_crypto_aes256_cbc(void) 1975178825Sdfr{ return &_hx509_crypto_aes256_cbc_data; } 1976178825Sdfr 1977178825Sdfr/* 1978178825Sdfr * 1979178825Sdfr */ 1980178825Sdfr 1981233294Sstasconst AlgorithmIdentifier * _hx509_crypto_default_sig_alg = 1982233294Sstas &_hx509_signature_rsa_with_sha256_data; 1983233294Sstasconst AlgorithmIdentifier * _hx509_crypto_default_digest_alg = 1984233294Sstas &_hx509_signature_sha256_data; 1985233294Sstasconst AlgorithmIdentifier * _hx509_crypto_default_secret_alg = 1986178825Sdfr &_hx509_crypto_aes128_cbc_data; 1987178825Sdfr 1988178825Sdfr/* 1989178825Sdfr * 1990178825Sdfr */ 1991178825Sdfr 1992178825Sdfrint 1993233294Sstashx509_private_key_init(hx509_private_key *key, 1994178825Sdfr hx509_private_key_ops *ops, 1995178825Sdfr void *keydata) 1996178825Sdfr{ 1997178825Sdfr *key = calloc(1, sizeof(**key)); 1998178825Sdfr if (*key == NULL) 1999178825Sdfr return ENOMEM; 2000178825Sdfr (*key)->ref = 1; 2001178825Sdfr (*key)->ops = ops; 2002178825Sdfr (*key)->private_key.keydata = keydata; 2003178825Sdfr return 0; 2004178825Sdfr} 2005178825Sdfr 2006178825Sdfrhx509_private_key 2007178825Sdfr_hx509_private_key_ref(hx509_private_key key) 2008178825Sdfr{ 2009233294Sstas if (key->ref == 0) 2010233294Sstas _hx509_abort("key refcount <= 0 on ref"); 2011178825Sdfr key->ref++; 2012233294Sstas if (key->ref == UINT_MAX) 2013233294Sstas _hx509_abort("key refcount == UINT_MAX on ref"); 2014178825Sdfr return key; 2015178825Sdfr} 2016178825Sdfr 2017178825Sdfrconst char * 2018178825Sdfr_hx509_private_pem_name(hx509_private_key key) 2019178825Sdfr{ 2020178825Sdfr return key->ops->pemtype; 2021178825Sdfr} 2022178825Sdfr 2023178825Sdfrint 2024233294Sstashx509_private_key_free(hx509_private_key *key) 2025178825Sdfr{ 2026178825Sdfr if (key == NULL || *key == NULL) 2027178825Sdfr return 0; 2028178825Sdfr 2029233294Sstas if ((*key)->ref == 0) 2030233294Sstas _hx509_abort("key refcount == 0 on free"); 2031178825Sdfr if (--(*key)->ref > 0) 2032178825Sdfr return 0; 2033178825Sdfr 2034233294Sstas if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0) { 2035233294Sstas if ((*key)->private_key.rsa) 2036233294Sstas RSA_free((*key)->private_key.rsa); 2037233294Sstas#ifdef HAVE_OPENSSL 2038233294Sstas } else if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) == 0) { 2039233294Sstas if ((*key)->private_key.ecdsa) 2040233294Sstas EC_KEY_free((*key)->private_key.ecdsa); 2041233294Sstas#endif 2042233294Sstas } 2043178825Sdfr (*key)->private_key.rsa = NULL; 2044178825Sdfr free(*key); 2045178825Sdfr *key = NULL; 2046178825Sdfr return 0; 2047178825Sdfr} 2048178825Sdfr 2049178825Sdfrvoid 2050233294Sstashx509_private_key_assign_rsa(hx509_private_key key, void *ptr) 2051178825Sdfr{ 2052178825Sdfr if (key->private_key.rsa) 2053178825Sdfr RSA_free(key->private_key.rsa); 2054178825Sdfr key->private_key.rsa = ptr; 2055233294Sstas key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION; 2056178825Sdfr key->md = &pkcs1_rsa_sha1_alg; 2057178825Sdfr} 2058178825Sdfr 2059233294Sstasint 2060178825Sdfr_hx509_private_key_oid(hx509_context context, 2061178825Sdfr const hx509_private_key key, 2062178825Sdfr heim_oid *data) 2063178825Sdfr{ 2064178825Sdfr int ret; 2065233294Sstas ret = der_copy_oid(key->ops->key_oid, data); 2066178825Sdfr if (ret) 2067178825Sdfr hx509_set_error_string(context, 0, ret, "malloc out of memory"); 2068178825Sdfr return ret; 2069178825Sdfr} 2070178825Sdfr 2071178825Sdfrint 2072178825Sdfr_hx509_private_key_exportable(hx509_private_key key) 2073178825Sdfr{ 2074178825Sdfr if (key->ops->export == NULL) 2075178825Sdfr return 0; 2076178825Sdfr return 1; 2077178825Sdfr} 2078178825Sdfr 2079178825SdfrBIGNUM * 2080178825Sdfr_hx509_private_key_get_internal(hx509_context context, 2081233294Sstas hx509_private_key key, 2082178825Sdfr const char *type) 2083178825Sdfr{ 2084178825Sdfr if (key->ops->get_internal == NULL) 2085178825Sdfr return NULL; 2086178825Sdfr return (*key->ops->get_internal)(context, key, type); 2087178825Sdfr} 2088178825Sdfr 2089233294Sstasint 2090178825Sdfr_hx509_private_key_export(hx509_context context, 2091178825Sdfr const hx509_private_key key, 2092233294Sstas hx509_key_format_t format, 2093178825Sdfr heim_octet_string *data) 2094178825Sdfr{ 2095178825Sdfr if (key->ops->export == NULL) { 2096178825Sdfr hx509_clear_error_string(context); 2097178825Sdfr return HX509_UNIMPLEMENTED_OPERATION; 2098178825Sdfr } 2099233294Sstas return (*key->ops->export)(context, key, format, data); 2100178825Sdfr} 2101178825Sdfr 2102178825Sdfr/* 2103178825Sdfr * 2104178825Sdfr */ 2105178825Sdfr 2106178825Sdfrstruct hx509cipher { 2107178825Sdfr const char *name; 2108233294Sstas int flags; 2109233294Sstas#define CIPHER_WEAK 1 2110233294Sstas const heim_oid *oid; 2111178825Sdfr const AlgorithmIdentifier *(*ai_func)(void); 2112178825Sdfr const EVP_CIPHER *(*evp_func)(void); 2113178825Sdfr int (*get_params)(hx509_context, const hx509_crypto, 2114178825Sdfr const heim_octet_string *, heim_octet_string *); 2115233294Sstas int (*set_params)(hx509_context, const heim_octet_string *, 2116178825Sdfr hx509_crypto, heim_octet_string *); 2117178825Sdfr}; 2118178825Sdfr 2119178825Sdfrstruct hx509_crypto_data { 2120178825Sdfr char *name; 2121233294Sstas int flags; 2122233294Sstas#define ALLOW_WEAK 1 2123233294Sstas 2124233294Sstas#define PADDING_NONE 2 2125233294Sstas#define PADDING_PKCS7 4 2126233294Sstas#define PADDING_FLAGS (2|4) 2127178825Sdfr const struct hx509cipher *cipher; 2128178825Sdfr const EVP_CIPHER *c; 2129178825Sdfr heim_octet_string key; 2130178825Sdfr heim_oid oid; 2131178825Sdfr void *param; 2132178825Sdfr}; 2133178825Sdfr 2134178825Sdfr/* 2135178825Sdfr * 2136178825Sdfr */ 2137178825Sdfr 2138233294Sstasstatic unsigned private_rc2_40_oid_data[] = { 127, 1 }; 2139178825Sdfr 2140233294Sstasstatic heim_oid asn1_oid_private_rc2_40 = 2141233294Sstas { 2, private_rc2_40_oid_data }; 2142178825Sdfr 2143178825Sdfr/* 2144178825Sdfr * 2145178825Sdfr */ 2146178825Sdfr 2147178825Sdfrstatic int 2148178825SdfrCMSCBCParam_get(hx509_context context, const hx509_crypto crypto, 2149178825Sdfr const heim_octet_string *ivec, heim_octet_string *param) 2150178825Sdfr{ 2151178825Sdfr size_t size; 2152178825Sdfr int ret; 2153178825Sdfr 2154178825Sdfr assert(crypto->param == NULL); 2155178825Sdfr if (ivec == NULL) 2156178825Sdfr return 0; 2157178825Sdfr 2158178825Sdfr ASN1_MALLOC_ENCODE(CMSCBCParameter, param->data, param->length, 2159178825Sdfr ivec, &size, ret); 2160178825Sdfr if (ret == 0 && size != param->length) 2161178825Sdfr _hx509_abort("Internal asn1 encoder failure"); 2162178825Sdfr if (ret) 2163178825Sdfr hx509_clear_error_string(context); 2164178825Sdfr return ret; 2165178825Sdfr} 2166178825Sdfr 2167178825Sdfrstatic int 2168178825SdfrCMSCBCParam_set(hx509_context context, const heim_octet_string *param, 2169178825Sdfr hx509_crypto crypto, heim_octet_string *ivec) 2170178825Sdfr{ 2171178825Sdfr int ret; 2172178825Sdfr if (ivec == NULL) 2173178825Sdfr return 0; 2174178825Sdfr 2175178825Sdfr ret = decode_CMSCBCParameter(param->data, param->length, ivec, NULL); 2176178825Sdfr if (ret) 2177178825Sdfr hx509_clear_error_string(context); 2178178825Sdfr 2179178825Sdfr return ret; 2180178825Sdfr} 2181178825Sdfr 2182178825Sdfrstruct _RC2_params { 2183178825Sdfr int maximum_effective_key; 2184178825Sdfr}; 2185178825Sdfr 2186178825Sdfrstatic int 2187178825SdfrCMSRC2CBCParam_get(hx509_context context, const hx509_crypto crypto, 2188178825Sdfr const heim_octet_string *ivec, heim_octet_string *param) 2189178825Sdfr{ 2190178825Sdfr CMSRC2CBCParameter rc2params; 2191178825Sdfr const struct _RC2_params *p = crypto->param; 2192178825Sdfr int maximum_effective_key = 128; 2193178825Sdfr size_t size; 2194178825Sdfr int ret; 2195178825Sdfr 2196178825Sdfr memset(&rc2params, 0, sizeof(rc2params)); 2197178825Sdfr 2198178825Sdfr if (p) 2199178825Sdfr maximum_effective_key = p->maximum_effective_key; 2200178825Sdfr 2201178825Sdfr switch(maximum_effective_key) { 2202178825Sdfr case 40: 2203178825Sdfr rc2params.rc2ParameterVersion = 160; 2204178825Sdfr break; 2205178825Sdfr case 64: 2206178825Sdfr rc2params.rc2ParameterVersion = 120; 2207178825Sdfr break; 2208178825Sdfr case 128: 2209178825Sdfr rc2params.rc2ParameterVersion = 58; 2210178825Sdfr break; 2211178825Sdfr } 2212178825Sdfr rc2params.iv = *ivec; 2213178825Sdfr 2214178825Sdfr ASN1_MALLOC_ENCODE(CMSRC2CBCParameter, param->data, param->length, 2215178825Sdfr &rc2params, &size, ret); 2216178825Sdfr if (ret == 0 && size != param->length) 2217178825Sdfr _hx509_abort("Internal asn1 encoder failure"); 2218178825Sdfr 2219178825Sdfr return ret; 2220178825Sdfr} 2221178825Sdfr 2222178825Sdfrstatic int 2223178825SdfrCMSRC2CBCParam_set(hx509_context context, const heim_octet_string *param, 2224178825Sdfr hx509_crypto crypto, heim_octet_string *ivec) 2225178825Sdfr{ 2226178825Sdfr CMSRC2CBCParameter rc2param; 2227178825Sdfr struct _RC2_params *p; 2228178825Sdfr size_t size; 2229178825Sdfr int ret; 2230178825Sdfr 2231178825Sdfr ret = decode_CMSRC2CBCParameter(param->data, param->length, 2232178825Sdfr &rc2param, &size); 2233178825Sdfr if (ret) { 2234178825Sdfr hx509_clear_error_string(context); 2235178825Sdfr return ret; 2236178825Sdfr } 2237178825Sdfr 2238178825Sdfr p = calloc(1, sizeof(*p)); 2239178825Sdfr if (p == NULL) { 2240178825Sdfr free_CMSRC2CBCParameter(&rc2param); 2241178825Sdfr hx509_clear_error_string(context); 2242178825Sdfr return ENOMEM; 2243178825Sdfr } 2244178825Sdfr switch(rc2param.rc2ParameterVersion) { 2245178825Sdfr case 160: 2246178825Sdfr crypto->c = EVP_rc2_40_cbc(); 2247178825Sdfr p->maximum_effective_key = 40; 2248178825Sdfr break; 2249178825Sdfr case 120: 2250178825Sdfr crypto->c = EVP_rc2_64_cbc(); 2251178825Sdfr p->maximum_effective_key = 64; 2252178825Sdfr break; 2253178825Sdfr case 58: 2254178825Sdfr crypto->c = EVP_rc2_cbc(); 2255178825Sdfr p->maximum_effective_key = 128; 2256178825Sdfr break; 2257178825Sdfr default: 2258178825Sdfr free(p); 2259178825Sdfr free_CMSRC2CBCParameter(&rc2param); 2260178825Sdfr return HX509_CRYPTO_SIG_INVALID_FORMAT; 2261178825Sdfr } 2262178825Sdfr if (ivec) 2263178825Sdfr ret = der_copy_octet_string(&rc2param.iv, ivec); 2264178825Sdfr free_CMSRC2CBCParameter(&rc2param); 2265178825Sdfr if (ret) { 2266178825Sdfr free(p); 2267178825Sdfr hx509_clear_error_string(context); 2268178825Sdfr } else 2269178825Sdfr crypto->param = p; 2270178825Sdfr 2271178825Sdfr return ret; 2272178825Sdfr} 2273178825Sdfr 2274178825Sdfr/* 2275178825Sdfr * 2276178825Sdfr */ 2277178825Sdfr 2278178825Sdfrstatic const struct hx509cipher ciphers[] = { 2279178825Sdfr { 2280178825Sdfr "rc2-cbc", 2281233294Sstas CIPHER_WEAK, 2282233294Sstas ASN1_OID_ID_PKCS3_RC2_CBC, 2283178825Sdfr NULL, 2284178825Sdfr EVP_rc2_cbc, 2285178825Sdfr CMSRC2CBCParam_get, 2286178825Sdfr CMSRC2CBCParam_set 2287178825Sdfr }, 2288178825Sdfr { 2289178825Sdfr "rc2-cbc", 2290233294Sstas CIPHER_WEAK, 2291233294Sstas ASN1_OID_ID_RSADSI_RC2_CBC, 2292178825Sdfr NULL, 2293178825Sdfr EVP_rc2_cbc, 2294178825Sdfr CMSRC2CBCParam_get, 2295178825Sdfr CMSRC2CBCParam_set 2296178825Sdfr }, 2297178825Sdfr { 2298178825Sdfr "rc2-40-cbc", 2299233294Sstas CIPHER_WEAK, 2300233294Sstas &asn1_oid_private_rc2_40, 2301178825Sdfr NULL, 2302178825Sdfr EVP_rc2_40_cbc, 2303178825Sdfr CMSRC2CBCParam_get, 2304178825Sdfr CMSRC2CBCParam_set 2305178825Sdfr }, 2306178825Sdfr { 2307178825Sdfr "des-ede3-cbc", 2308233294Sstas 0, 2309233294Sstas ASN1_OID_ID_PKCS3_DES_EDE3_CBC, 2310178825Sdfr NULL, 2311178825Sdfr EVP_des_ede3_cbc, 2312178825Sdfr CMSCBCParam_get, 2313178825Sdfr CMSCBCParam_set 2314178825Sdfr }, 2315178825Sdfr { 2316178825Sdfr "des-ede3-cbc", 2317233294Sstas 0, 2318233294Sstas ASN1_OID_ID_RSADSI_DES_EDE3_CBC, 2319178825Sdfr hx509_crypto_des_rsdi_ede3_cbc, 2320178825Sdfr EVP_des_ede3_cbc, 2321178825Sdfr CMSCBCParam_get, 2322178825Sdfr CMSCBCParam_set 2323178825Sdfr }, 2324178825Sdfr { 2325178825Sdfr "aes-128-cbc", 2326233294Sstas 0, 2327233294Sstas ASN1_OID_ID_AES_128_CBC, 2328178825Sdfr hx509_crypto_aes128_cbc, 2329178825Sdfr EVP_aes_128_cbc, 2330178825Sdfr CMSCBCParam_get, 2331178825Sdfr CMSCBCParam_set 2332178825Sdfr }, 2333178825Sdfr { 2334178825Sdfr "aes-192-cbc", 2335233294Sstas 0, 2336233294Sstas ASN1_OID_ID_AES_192_CBC, 2337178825Sdfr NULL, 2338178825Sdfr EVP_aes_192_cbc, 2339178825Sdfr CMSCBCParam_get, 2340178825Sdfr CMSCBCParam_set 2341178825Sdfr }, 2342178825Sdfr { 2343178825Sdfr "aes-256-cbc", 2344233294Sstas 0, 2345233294Sstas ASN1_OID_ID_AES_256_CBC, 2346178825Sdfr hx509_crypto_aes256_cbc, 2347178825Sdfr EVP_aes_256_cbc, 2348178825Sdfr CMSCBCParam_get, 2349178825Sdfr CMSCBCParam_set 2350178825Sdfr } 2351178825Sdfr}; 2352178825Sdfr 2353178825Sdfrstatic const struct hx509cipher * 2354178825Sdfrfind_cipher_by_oid(const heim_oid *oid) 2355178825Sdfr{ 2356233294Sstas size_t i; 2357178825Sdfr 2358178825Sdfr for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++) 2359233294Sstas if (der_heim_oid_cmp(oid, ciphers[i].oid) == 0) 2360178825Sdfr return &ciphers[i]; 2361178825Sdfr 2362178825Sdfr return NULL; 2363178825Sdfr} 2364178825Sdfr 2365178825Sdfrstatic const struct hx509cipher * 2366178825Sdfrfind_cipher_by_name(const char *name) 2367178825Sdfr{ 2368233294Sstas size_t i; 2369178825Sdfr 2370178825Sdfr for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++) 2371178825Sdfr if (strcasecmp(name, ciphers[i].name) == 0) 2372178825Sdfr return &ciphers[i]; 2373178825Sdfr 2374178825Sdfr return NULL; 2375178825Sdfr} 2376178825Sdfr 2377178825Sdfr 2378178825Sdfrconst heim_oid * 2379178825Sdfrhx509_crypto_enctype_by_name(const char *name) 2380178825Sdfr{ 2381178825Sdfr const struct hx509cipher *cipher; 2382178825Sdfr 2383178825Sdfr cipher = find_cipher_by_name(name); 2384178825Sdfr if (cipher == NULL) 2385178825Sdfr return NULL; 2386233294Sstas return cipher->oid; 2387178825Sdfr} 2388178825Sdfr 2389178825Sdfrint 2390178825Sdfrhx509_crypto_init(hx509_context context, 2391178825Sdfr const char *provider, 2392178825Sdfr const heim_oid *enctype, 2393178825Sdfr hx509_crypto *crypto) 2394178825Sdfr{ 2395178825Sdfr const struct hx509cipher *cipher; 2396178825Sdfr 2397178825Sdfr *crypto = NULL; 2398178825Sdfr 2399178825Sdfr cipher = find_cipher_by_oid(enctype); 2400178825Sdfr if (cipher == NULL) { 2401178825Sdfr hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP, 2402178825Sdfr "Algorithm not supported"); 2403178825Sdfr return HX509_ALG_NOT_SUPP; 2404178825Sdfr } 2405178825Sdfr 2406178825Sdfr *crypto = calloc(1, sizeof(**crypto)); 2407178825Sdfr if (*crypto == NULL) { 2408178825Sdfr hx509_clear_error_string(context); 2409178825Sdfr return ENOMEM; 2410178825Sdfr } 2411178825Sdfr 2412233294Sstas (*crypto)->flags = PADDING_PKCS7; 2413178825Sdfr (*crypto)->cipher = cipher; 2414178825Sdfr (*crypto)->c = (*cipher->evp_func)(); 2415178825Sdfr 2416178825Sdfr if (der_copy_oid(enctype, &(*crypto)->oid)) { 2417178825Sdfr hx509_crypto_destroy(*crypto); 2418178825Sdfr *crypto = NULL; 2419178825Sdfr hx509_clear_error_string(context); 2420178825Sdfr return ENOMEM; 2421178825Sdfr } 2422178825Sdfr 2423178825Sdfr return 0; 2424178825Sdfr} 2425178825Sdfr 2426178825Sdfrconst char * 2427178825Sdfrhx509_crypto_provider(hx509_crypto crypto) 2428178825Sdfr{ 2429178825Sdfr return "unknown"; 2430178825Sdfr} 2431178825Sdfr 2432178825Sdfrvoid 2433178825Sdfrhx509_crypto_destroy(hx509_crypto crypto) 2434178825Sdfr{ 2435178825Sdfr if (crypto->name) 2436178825Sdfr free(crypto->name); 2437178825Sdfr if (crypto->key.data) 2438178825Sdfr free(crypto->key.data); 2439178825Sdfr if (crypto->param) 2440178825Sdfr free(crypto->param); 2441178825Sdfr der_free_oid(&crypto->oid); 2442178825Sdfr memset(crypto, 0, sizeof(*crypto)); 2443178825Sdfr free(crypto); 2444178825Sdfr} 2445178825Sdfr 2446178825Sdfrint 2447178825Sdfrhx509_crypto_set_key_name(hx509_crypto crypto, const char *name) 2448178825Sdfr{ 2449178825Sdfr return 0; 2450178825Sdfr} 2451178825Sdfr 2452233294Sstasvoid 2453233294Sstashx509_crypto_allow_weak(hx509_crypto crypto) 2454233294Sstas{ 2455233294Sstas crypto->flags |= ALLOW_WEAK; 2456233294Sstas} 2457233294Sstas 2458233294Sstasvoid 2459233294Sstashx509_crypto_set_padding(hx509_crypto crypto, int padding_type) 2460233294Sstas{ 2461233294Sstas switch (padding_type) { 2462233294Sstas case HX509_CRYPTO_PADDING_PKCS7: 2463233294Sstas crypto->flags &= ~PADDING_FLAGS; 2464233294Sstas crypto->flags |= PADDING_PKCS7; 2465233294Sstas break; 2466233294Sstas case HX509_CRYPTO_PADDING_NONE: 2467233294Sstas crypto->flags &= ~PADDING_FLAGS; 2468233294Sstas crypto->flags |= PADDING_NONE; 2469233294Sstas break; 2470233294Sstas default: 2471233294Sstas _hx509_abort("Invalid padding"); 2472233294Sstas } 2473233294Sstas} 2474233294Sstas 2475178825Sdfrint 2476178825Sdfrhx509_crypto_set_key_data(hx509_crypto crypto, const void *data, size_t length) 2477178825Sdfr{ 2478233294Sstas if (EVP_CIPHER_key_length(crypto->c) > (int)length) 2479178825Sdfr return HX509_CRYPTO_INTERNAL_ERROR; 2480178825Sdfr 2481178825Sdfr if (crypto->key.data) { 2482178825Sdfr free(crypto->key.data); 2483178825Sdfr crypto->key.data = NULL; 2484178825Sdfr crypto->key.length = 0; 2485178825Sdfr } 2486178825Sdfr crypto->key.data = malloc(length); 2487178825Sdfr if (crypto->key.data == NULL) 2488178825Sdfr return ENOMEM; 2489178825Sdfr memcpy(crypto->key.data, data, length); 2490178825Sdfr crypto->key.length = length; 2491178825Sdfr 2492178825Sdfr return 0; 2493178825Sdfr} 2494178825Sdfr 2495178825Sdfrint 2496178825Sdfrhx509_crypto_set_random_key(hx509_crypto crypto, heim_octet_string *key) 2497178825Sdfr{ 2498178825Sdfr if (crypto->key.data) { 2499178825Sdfr free(crypto->key.data); 2500178825Sdfr crypto->key.length = 0; 2501178825Sdfr } 2502178825Sdfr 2503178825Sdfr crypto->key.length = EVP_CIPHER_key_length(crypto->c); 2504178825Sdfr crypto->key.data = malloc(crypto->key.length); 2505178825Sdfr if (crypto->key.data == NULL) { 2506178825Sdfr crypto->key.length = 0; 2507178825Sdfr return ENOMEM; 2508178825Sdfr } 2509178825Sdfr if (RAND_bytes(crypto->key.data, crypto->key.length) <= 0) { 2510178825Sdfr free(crypto->key.data); 2511178825Sdfr crypto->key.data = NULL; 2512178825Sdfr crypto->key.length = 0; 2513178825Sdfr return HX509_CRYPTO_INTERNAL_ERROR; 2514178825Sdfr } 2515178825Sdfr if (key) 2516178825Sdfr return der_copy_octet_string(&crypto->key, key); 2517178825Sdfr else 2518178825Sdfr return 0; 2519178825Sdfr} 2520178825Sdfr 2521178825Sdfrint 2522178825Sdfrhx509_crypto_set_params(hx509_context context, 2523233294Sstas hx509_crypto crypto, 2524178825Sdfr const heim_octet_string *param, 2525178825Sdfr heim_octet_string *ivec) 2526178825Sdfr{ 2527178825Sdfr return (*crypto->cipher->set_params)(context, param, crypto, ivec); 2528178825Sdfr} 2529178825Sdfr 2530178825Sdfrint 2531178825Sdfrhx509_crypto_get_params(hx509_context context, 2532233294Sstas hx509_crypto crypto, 2533178825Sdfr const heim_octet_string *ivec, 2534178825Sdfr heim_octet_string *param) 2535178825Sdfr{ 2536178825Sdfr return (*crypto->cipher->get_params)(context, crypto, ivec, param); 2537178825Sdfr} 2538178825Sdfr 2539178825Sdfrint 2540178825Sdfrhx509_crypto_random_iv(hx509_crypto crypto, heim_octet_string *ivec) 2541178825Sdfr{ 2542178825Sdfr ivec->length = EVP_CIPHER_iv_length(crypto->c); 2543178825Sdfr ivec->data = malloc(ivec->length); 2544178825Sdfr if (ivec->data == NULL) { 2545178825Sdfr ivec->length = 0; 2546178825Sdfr return ENOMEM; 2547178825Sdfr } 2548178825Sdfr 2549178825Sdfr if (RAND_bytes(ivec->data, ivec->length) <= 0) { 2550178825Sdfr free(ivec->data); 2551178825Sdfr ivec->data = NULL; 2552178825Sdfr ivec->length = 0; 2553178825Sdfr return HX509_CRYPTO_INTERNAL_ERROR; 2554178825Sdfr } 2555178825Sdfr return 0; 2556178825Sdfr} 2557178825Sdfr 2558178825Sdfrint 2559178825Sdfrhx509_crypto_encrypt(hx509_crypto crypto, 2560178825Sdfr const void *data, 2561178825Sdfr const size_t length, 2562178825Sdfr const heim_octet_string *ivec, 2563178825Sdfr heim_octet_string **ciphertext) 2564178825Sdfr{ 2565178825Sdfr EVP_CIPHER_CTX evp; 2566233294Sstas size_t padsize, bsize; 2567178825Sdfr int ret; 2568178825Sdfr 2569178825Sdfr *ciphertext = NULL; 2570178825Sdfr 2571233294Sstas if ((crypto->cipher->flags & CIPHER_WEAK) && 2572233294Sstas (crypto->flags & ALLOW_WEAK) == 0) 2573233294Sstas return HX509_CRYPTO_ALGORITHM_BEST_BEFORE; 2574178825Sdfr 2575233294Sstas assert(EVP_CIPHER_iv_length(crypto->c) == (int)ivec->length); 2576233294Sstas 2577178825Sdfr EVP_CIPHER_CTX_init(&evp); 2578178825Sdfr 2579178825Sdfr ret = EVP_CipherInit_ex(&evp, crypto->c, NULL, 2580178825Sdfr crypto->key.data, ivec->data, 1); 2581178825Sdfr if (ret != 1) { 2582178825Sdfr EVP_CIPHER_CTX_cleanup(&evp); 2583178825Sdfr ret = HX509_CRYPTO_INTERNAL_ERROR; 2584178825Sdfr goto out; 2585178825Sdfr } 2586178825Sdfr 2587178825Sdfr *ciphertext = calloc(1, sizeof(**ciphertext)); 2588178825Sdfr if (*ciphertext == NULL) { 2589178825Sdfr ret = ENOMEM; 2590178825Sdfr goto out; 2591178825Sdfr } 2592233294Sstas 2593233294Sstas assert(crypto->flags & PADDING_FLAGS); 2594233294Sstas 2595233294Sstas bsize = EVP_CIPHER_block_size(crypto->c); 2596233294Sstas padsize = 0; 2597233294Sstas 2598233294Sstas if (crypto->flags & PADDING_NONE) { 2599233294Sstas if (bsize != 1 && (length % bsize) != 0) 2600233294Sstas return HX509_CMS_PADDING_ERROR; 2601233294Sstas } else if (crypto->flags & PADDING_PKCS7) { 2602233294Sstas if (bsize != 1) 2603233294Sstas padsize = bsize - (length % bsize); 2604178825Sdfr } 2605233294Sstas 2606178825Sdfr (*ciphertext)->length = length + padsize; 2607178825Sdfr (*ciphertext)->data = malloc(length + padsize); 2608178825Sdfr if ((*ciphertext)->data == NULL) { 2609178825Sdfr ret = ENOMEM; 2610178825Sdfr goto out; 2611178825Sdfr } 2612233294Sstas 2613178825Sdfr memcpy((*ciphertext)->data, data, length); 2614178825Sdfr if (padsize) { 2615233294Sstas size_t i; 2616178825Sdfr unsigned char *p = (*ciphertext)->data; 2617178825Sdfr p += length; 2618178825Sdfr for (i = 0; i < padsize; i++) 2619178825Sdfr *p++ = padsize; 2620178825Sdfr } 2621178825Sdfr 2622178825Sdfr ret = EVP_Cipher(&evp, (*ciphertext)->data, 2623178825Sdfr (*ciphertext)->data, 2624178825Sdfr length + padsize); 2625178825Sdfr if (ret != 1) { 2626178825Sdfr ret = HX509_CRYPTO_INTERNAL_ERROR; 2627178825Sdfr goto out; 2628178825Sdfr } 2629178825Sdfr ret = 0; 2630178825Sdfr 2631178825Sdfr out: 2632178825Sdfr if (ret) { 2633178825Sdfr if (*ciphertext) { 2634178825Sdfr if ((*ciphertext)->data) { 2635178825Sdfr free((*ciphertext)->data); 2636178825Sdfr } 2637178825Sdfr free(*ciphertext); 2638178825Sdfr *ciphertext = NULL; 2639178825Sdfr } 2640178825Sdfr } 2641178825Sdfr EVP_CIPHER_CTX_cleanup(&evp); 2642178825Sdfr 2643178825Sdfr return ret; 2644178825Sdfr} 2645178825Sdfr 2646178825Sdfrint 2647178825Sdfrhx509_crypto_decrypt(hx509_crypto crypto, 2648178825Sdfr const void *data, 2649178825Sdfr const size_t length, 2650178825Sdfr heim_octet_string *ivec, 2651178825Sdfr heim_octet_string *clear) 2652178825Sdfr{ 2653178825Sdfr EVP_CIPHER_CTX evp; 2654178825Sdfr void *idata = NULL; 2655178825Sdfr int ret; 2656178825Sdfr 2657178825Sdfr clear->data = NULL; 2658178825Sdfr clear->length = 0; 2659178825Sdfr 2660233294Sstas if ((crypto->cipher->flags & CIPHER_WEAK) && 2661233294Sstas (crypto->flags & ALLOW_WEAK) == 0) 2662233294Sstas return HX509_CRYPTO_ALGORITHM_BEST_BEFORE; 2663233294Sstas 2664233294Sstas if (ivec && EVP_CIPHER_iv_length(crypto->c) < (int)ivec->length) 2665178825Sdfr return HX509_CRYPTO_INTERNAL_ERROR; 2666178825Sdfr 2667178825Sdfr if (crypto->key.data == NULL) 2668178825Sdfr return HX509_CRYPTO_INTERNAL_ERROR; 2669178825Sdfr 2670178825Sdfr if (ivec) 2671178825Sdfr idata = ivec->data; 2672178825Sdfr 2673178825Sdfr EVP_CIPHER_CTX_init(&evp); 2674178825Sdfr 2675178825Sdfr ret = EVP_CipherInit_ex(&evp, crypto->c, NULL, 2676178825Sdfr crypto->key.data, idata, 0); 2677178825Sdfr if (ret != 1) { 2678178825Sdfr EVP_CIPHER_CTX_cleanup(&evp); 2679178825Sdfr return HX509_CRYPTO_INTERNAL_ERROR; 2680178825Sdfr } 2681178825Sdfr 2682178825Sdfr clear->length = length; 2683178825Sdfr clear->data = malloc(length); 2684178825Sdfr if (clear->data == NULL) { 2685178825Sdfr EVP_CIPHER_CTX_cleanup(&evp); 2686178825Sdfr clear->length = 0; 2687178825Sdfr return ENOMEM; 2688178825Sdfr } 2689178825Sdfr 2690178825Sdfr if (EVP_Cipher(&evp, clear->data, data, length) != 1) { 2691178825Sdfr return HX509_CRYPTO_INTERNAL_ERROR; 2692178825Sdfr } 2693178825Sdfr EVP_CIPHER_CTX_cleanup(&evp); 2694178825Sdfr 2695233294Sstas if ((crypto->flags & PADDING_PKCS7) && EVP_CIPHER_block_size(crypto->c) > 1) { 2696178825Sdfr int padsize; 2697233294Sstas unsigned char *p; 2698178825Sdfr int j, bsize = EVP_CIPHER_block_size(crypto->c); 2699178825Sdfr 2700233294Sstas if ((int)clear->length < bsize) { 2701178825Sdfr ret = HX509_CMS_PADDING_ERROR; 2702178825Sdfr goto out; 2703178825Sdfr } 2704178825Sdfr 2705178825Sdfr p = clear->data; 2706178825Sdfr p += clear->length - 1; 2707178825Sdfr padsize = *p; 2708178825Sdfr if (padsize > bsize) { 2709178825Sdfr ret = HX509_CMS_PADDING_ERROR; 2710178825Sdfr goto out; 2711178825Sdfr } 2712178825Sdfr clear->length -= padsize; 2713178825Sdfr for (j = 0; j < padsize; j++) { 2714178825Sdfr if (*p-- != padsize) { 2715178825Sdfr ret = HX509_CMS_PADDING_ERROR; 2716178825Sdfr goto out; 2717178825Sdfr } 2718178825Sdfr } 2719178825Sdfr } 2720178825Sdfr 2721178825Sdfr return 0; 2722178825Sdfr 2723178825Sdfr out: 2724178825Sdfr if (clear->data) 2725178825Sdfr free(clear->data); 2726178825Sdfr clear->data = NULL; 2727178825Sdfr clear->length = 0; 2728178825Sdfr return ret; 2729178825Sdfr} 2730178825Sdfr 2731178825Sdfrtypedef int (*PBE_string2key_func)(hx509_context, 2732178825Sdfr const char *, 2733178825Sdfr const heim_octet_string *, 2734233294Sstas hx509_crypto *, heim_octet_string *, 2735178825Sdfr heim_octet_string *, 2736178825Sdfr const heim_oid *, const EVP_MD *); 2737178825Sdfr 2738178825Sdfrstatic int 2739178825SdfrPBE_string2key(hx509_context context, 2740178825Sdfr const char *password, 2741178825Sdfr const heim_octet_string *parameters, 2742233294Sstas hx509_crypto *crypto, 2743178825Sdfr heim_octet_string *key, heim_octet_string *iv, 2744178825Sdfr const heim_oid *enc_oid, 2745178825Sdfr const EVP_MD *md) 2746178825Sdfr{ 2747178825Sdfr PKCS12_PBEParams p12params; 2748178825Sdfr int passwordlen; 2749178825Sdfr hx509_crypto c; 2750178825Sdfr int iter, saltlen, ret; 2751178825Sdfr unsigned char *salt; 2752178825Sdfr 2753178825Sdfr passwordlen = password ? strlen(password) : 0; 2754178825Sdfr 2755178825Sdfr if (parameters == NULL) 2756178825Sdfr return HX509_ALG_NOT_SUPP; 2757178825Sdfr 2758178825Sdfr ret = decode_PKCS12_PBEParams(parameters->data, 2759178825Sdfr parameters->length, 2760178825Sdfr &p12params, NULL); 2761178825Sdfr if (ret) 2762178825Sdfr goto out; 2763178825Sdfr 2764178825Sdfr if (p12params.iterations) 2765178825Sdfr iter = *p12params.iterations; 2766178825Sdfr else 2767178825Sdfr iter = 1; 2768178825Sdfr salt = p12params.salt.data; 2769178825Sdfr saltlen = p12params.salt.length; 2770178825Sdfr 2771233294Sstas if (!PKCS12_key_gen (password, passwordlen, salt, saltlen, 2772178825Sdfr PKCS12_KEY_ID, iter, key->length, key->data, md)) { 2773178825Sdfr ret = HX509_CRYPTO_INTERNAL_ERROR; 2774178825Sdfr goto out; 2775178825Sdfr } 2776233294Sstas 2777233294Sstas if (!PKCS12_key_gen (password, passwordlen, salt, saltlen, 2778178825Sdfr PKCS12_IV_ID, iter, iv->length, iv->data, md)) { 2779178825Sdfr ret = HX509_CRYPTO_INTERNAL_ERROR; 2780178825Sdfr goto out; 2781178825Sdfr } 2782178825Sdfr 2783178825Sdfr ret = hx509_crypto_init(context, NULL, enc_oid, &c); 2784178825Sdfr if (ret) 2785178825Sdfr goto out; 2786178825Sdfr 2787233294Sstas hx509_crypto_allow_weak(c); 2788233294Sstas 2789178825Sdfr ret = hx509_crypto_set_key_data(c, key->data, key->length); 2790178825Sdfr if (ret) { 2791178825Sdfr hx509_crypto_destroy(c); 2792178825Sdfr goto out; 2793178825Sdfr } 2794178825Sdfr 2795178825Sdfr *crypto = c; 2796178825Sdfrout: 2797178825Sdfr free_PKCS12_PBEParams(&p12params); 2798178825Sdfr return ret; 2799178825Sdfr} 2800178825Sdfr 2801178825Sdfrstatic const heim_oid * 2802233294Sstasfind_string2key(const heim_oid *oid, 2803233294Sstas const EVP_CIPHER **c, 2804178825Sdfr const EVP_MD **md, 2805178825Sdfr PBE_string2key_func *s2k) 2806178825Sdfr{ 2807233294Sstas if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND40BITRC2_CBC) == 0) { 2808178825Sdfr *c = EVP_rc2_40_cbc(); 2809178825Sdfr *md = EVP_sha1(); 2810178825Sdfr *s2k = PBE_string2key; 2811233294Sstas return &asn1_oid_private_rc2_40; 2812233294Sstas } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND128BITRC2_CBC) == 0) { 2813178825Sdfr *c = EVP_rc2_cbc(); 2814178825Sdfr *md = EVP_sha1(); 2815178825Sdfr *s2k = PBE_string2key; 2816233294Sstas return ASN1_OID_ID_PKCS3_RC2_CBC; 2817178825Sdfr#if 0 2818233294Sstas } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND40BITRC4) == 0) { 2819178825Sdfr *c = EVP_rc4_40(); 2820178825Sdfr *md = EVP_sha1(); 2821178825Sdfr *s2k = PBE_string2key; 2822178825Sdfr return NULL; 2823233294Sstas } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND128BITRC4) == 0) { 2824178825Sdfr *c = EVP_rc4(); 2825178825Sdfr *md = EVP_sha1(); 2826178825Sdfr *s2k = PBE_string2key; 2827233294Sstas return ASN1_OID_ID_PKCS3_RC4; 2828178825Sdfr#endif 2829233294Sstas } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND3_KEYTRIPLEDES_CBC) == 0) { 2830178825Sdfr *c = EVP_des_ede3_cbc(); 2831178825Sdfr *md = EVP_sha1(); 2832178825Sdfr *s2k = PBE_string2key; 2833233294Sstas return ASN1_OID_ID_PKCS3_DES_EDE3_CBC; 2834178825Sdfr } 2835178825Sdfr 2836178825Sdfr return NULL; 2837178825Sdfr} 2838178825Sdfr 2839178825Sdfr/* 2840178825Sdfr * 2841178825Sdfr */ 2842178825Sdfr 2843178825Sdfrint 2844178825Sdfr_hx509_pbe_encrypt(hx509_context context, 2845178825Sdfr hx509_lock lock, 2846178825Sdfr const AlgorithmIdentifier *ai, 2847178825Sdfr const heim_octet_string *content, 2848178825Sdfr heim_octet_string *econtent) 2849178825Sdfr{ 2850178825Sdfr hx509_clear_error_string(context); 2851178825Sdfr return EINVAL; 2852178825Sdfr} 2853178825Sdfr 2854178825Sdfr/* 2855178825Sdfr * 2856178825Sdfr */ 2857178825Sdfr 2858178825Sdfrint 2859178825Sdfr_hx509_pbe_decrypt(hx509_context context, 2860178825Sdfr hx509_lock lock, 2861178825Sdfr const AlgorithmIdentifier *ai, 2862178825Sdfr const heim_octet_string *econtent, 2863178825Sdfr heim_octet_string *content) 2864178825Sdfr{ 2865178825Sdfr const struct _hx509_password *pw; 2866178825Sdfr heim_octet_string key, iv; 2867178825Sdfr const heim_oid *enc_oid; 2868178825Sdfr const EVP_CIPHER *c; 2869178825Sdfr const EVP_MD *md; 2870178825Sdfr PBE_string2key_func s2k; 2871233294Sstas int ret = 0; 2872233294Sstas size_t i; 2873178825Sdfr 2874178825Sdfr memset(&key, 0, sizeof(key)); 2875178825Sdfr memset(&iv, 0, sizeof(iv)); 2876178825Sdfr 2877178825Sdfr memset(content, 0, sizeof(*content)); 2878178825Sdfr 2879178825Sdfr enc_oid = find_string2key(&ai->algorithm, &c, &md, &s2k); 2880178825Sdfr if (enc_oid == NULL) { 2881178825Sdfr hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP, 2882178825Sdfr "String to key algorithm not supported"); 2883178825Sdfr ret = HX509_ALG_NOT_SUPP; 2884178825Sdfr goto out; 2885178825Sdfr } 2886178825Sdfr 2887178825Sdfr key.length = EVP_CIPHER_key_length(c); 2888178825Sdfr key.data = malloc(key.length); 2889178825Sdfr if (key.data == NULL) { 2890178825Sdfr ret = ENOMEM; 2891178825Sdfr hx509_clear_error_string(context); 2892178825Sdfr goto out; 2893178825Sdfr } 2894178825Sdfr 2895178825Sdfr iv.length = EVP_CIPHER_iv_length(c); 2896178825Sdfr iv.data = malloc(iv.length); 2897178825Sdfr if (iv.data == NULL) { 2898178825Sdfr ret = ENOMEM; 2899178825Sdfr hx509_clear_error_string(context); 2900178825Sdfr goto out; 2901178825Sdfr } 2902178825Sdfr 2903178825Sdfr pw = _hx509_lock_get_passwords(lock); 2904178825Sdfr 2905178825Sdfr ret = HX509_CRYPTO_INTERNAL_ERROR; 2906178825Sdfr for (i = 0; i < pw->len + 1; i++) { 2907178825Sdfr hx509_crypto crypto; 2908178825Sdfr const char *password; 2909178825Sdfr 2910178825Sdfr if (i < pw->len) 2911178825Sdfr password = pw->val[i]; 2912178825Sdfr else if (i < pw->len + 1) 2913178825Sdfr password = ""; 2914178825Sdfr else 2915178825Sdfr password = NULL; 2916178825Sdfr 2917233294Sstas ret = (*s2k)(context, password, ai->parameters, &crypto, 2918178825Sdfr &key, &iv, enc_oid, md); 2919178825Sdfr if (ret) 2920178825Sdfr goto out; 2921178825Sdfr 2922178825Sdfr ret = hx509_crypto_decrypt(crypto, 2923178825Sdfr econtent->data, 2924178825Sdfr econtent->length, 2925178825Sdfr &iv, 2926178825Sdfr content); 2927178825Sdfr hx509_crypto_destroy(crypto); 2928178825Sdfr if (ret == 0) 2929178825Sdfr goto out; 2930233294Sstas 2931178825Sdfr } 2932178825Sdfrout: 2933178825Sdfr if (key.data) 2934178825Sdfr der_free_octet_string(&key); 2935178825Sdfr if (iv.data) 2936178825Sdfr der_free_octet_string(&iv); 2937178825Sdfr return ret; 2938178825Sdfr} 2939178825Sdfr 2940178825Sdfr/* 2941178825Sdfr * 2942178825Sdfr */ 2943178825Sdfr 2944178825Sdfr 2945233294Sstasstatic int 2946233294Sstasmatch_keys_rsa(hx509_cert c, hx509_private_key private_key) 2947178825Sdfr{ 2948178825Sdfr const Certificate *cert; 2949178825Sdfr const SubjectPublicKeyInfo *spi; 2950178825Sdfr RSAPublicKey pk; 2951178825Sdfr RSA *rsa; 2952178825Sdfr size_t size; 2953178825Sdfr int ret; 2954178825Sdfr 2955178825Sdfr if (private_key->private_key.rsa == NULL) 2956178825Sdfr return 0; 2957178825Sdfr 2958178825Sdfr rsa = private_key->private_key.rsa; 2959178825Sdfr if (rsa->d == NULL || rsa->p == NULL || rsa->q == NULL) 2960178825Sdfr return 0; 2961178825Sdfr 2962178825Sdfr cert = _hx509_get_cert(c); 2963178825Sdfr spi = &cert->tbsCertificate.subjectPublicKeyInfo; 2964178825Sdfr 2965178825Sdfr rsa = RSA_new(); 2966178825Sdfr if (rsa == NULL) 2967178825Sdfr return 0; 2968178825Sdfr 2969178825Sdfr ret = decode_RSAPublicKey(spi->subjectPublicKey.data, 2970178825Sdfr spi->subjectPublicKey.length / 8, 2971178825Sdfr &pk, &size); 2972178825Sdfr if (ret) { 2973178825Sdfr RSA_free(rsa); 2974178825Sdfr return 0; 2975178825Sdfr } 2976178825Sdfr rsa->n = heim_int2BN(&pk.modulus); 2977178825Sdfr rsa->e = heim_int2BN(&pk.publicExponent); 2978178825Sdfr 2979178825Sdfr free_RSAPublicKey(&pk); 2980178825Sdfr 2981178825Sdfr rsa->d = BN_dup(private_key->private_key.rsa->d); 2982178825Sdfr rsa->p = BN_dup(private_key->private_key.rsa->p); 2983178825Sdfr rsa->q = BN_dup(private_key->private_key.rsa->q); 2984178825Sdfr rsa->dmp1 = BN_dup(private_key->private_key.rsa->dmp1); 2985178825Sdfr rsa->dmq1 = BN_dup(private_key->private_key.rsa->dmq1); 2986178825Sdfr rsa->iqmp = BN_dup(private_key->private_key.rsa->iqmp); 2987178825Sdfr 2988233294Sstas if (rsa->n == NULL || rsa->e == NULL || 2989178825Sdfr rsa->d == NULL || rsa->p == NULL|| rsa->q == NULL || 2990178825Sdfr rsa->dmp1 == NULL || rsa->dmq1 == NULL) { 2991178825Sdfr RSA_free(rsa); 2992178825Sdfr return 0; 2993178825Sdfr } 2994178825Sdfr 2995178825Sdfr ret = RSA_check_key(rsa); 2996178825Sdfr RSA_free(rsa); 2997178825Sdfr 2998178825Sdfr return ret == 1; 2999178825Sdfr} 3000178825Sdfr 3001233294Sstasstatic int 3002233294Sstasmatch_keys_ec(hx509_cert c, hx509_private_key private_key) 3003233294Sstas{ 3004233294Sstas return 1; /* XXX use EC_KEY_check_key */ 3005233294Sstas} 3006233294Sstas 3007233294Sstas 3008233294Sstasint 3009233294Sstas_hx509_match_keys(hx509_cert c, hx509_private_key key) 3010233294Sstas{ 3011233294Sstas if (der_heim_oid_cmp(key->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0) 3012233294Sstas return match_keys_rsa(c, key); 3013233294Sstas if (der_heim_oid_cmp(key->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) == 0) 3014233294Sstas return match_keys_ec(c, key); 3015233294Sstas return 0; 3016233294Sstas 3017233294Sstas} 3018233294Sstas 3019233294Sstas 3020178825Sdfrstatic const heim_oid * 3021178825Sdfrfind_keytype(const hx509_private_key key) 3022178825Sdfr{ 3023178825Sdfr const struct signature_alg *md; 3024178825Sdfr 3025178825Sdfr if (key == NULL) 3026178825Sdfr return NULL; 3027178825Sdfr 3028178825Sdfr md = find_sig_alg(key->signature_alg); 3029178825Sdfr if (md == NULL) 3030178825Sdfr return NULL; 3031233294Sstas return md->key_oid; 3032178825Sdfr} 3033178825Sdfr 3034178825Sdfrint 3035178825Sdfrhx509_crypto_select(const hx509_context context, 3036178825Sdfr int type, 3037178825Sdfr const hx509_private_key source, 3038178825Sdfr hx509_peer_info peer, 3039178825Sdfr AlgorithmIdentifier *selected) 3040178825Sdfr{ 3041233294Sstas const AlgorithmIdentifier *def = NULL; 3042178825Sdfr size_t i, j; 3043178825Sdfr int ret, bits; 3044178825Sdfr 3045178825Sdfr memset(selected, 0, sizeof(*selected)); 3046178825Sdfr 3047178825Sdfr if (type == HX509_SELECT_DIGEST) { 3048178825Sdfr bits = SIG_DIGEST; 3049233294Sstas if (source) 3050233294Sstas def = alg_for_privatekey(source, type); 3051233294Sstas if (def == NULL) 3052233294Sstas def = _hx509_crypto_default_digest_alg; 3053178825Sdfr } else if (type == HX509_SELECT_PUBLIC_SIG) { 3054178825Sdfr bits = SIG_PUBLIC_SIG; 3055233294Sstas /* XXX depend on `source�� and `peer�� */ 3056233294Sstas if (source) 3057233294Sstas def = alg_for_privatekey(source, type); 3058233294Sstas if (def == NULL) 3059233294Sstas def = _hx509_crypto_default_sig_alg; 3060178825Sdfr } else if (type == HX509_SELECT_SECRET_ENC) { 3061178825Sdfr bits = SIG_SECRET; 3062178825Sdfr def = _hx509_crypto_default_secret_alg; 3063178825Sdfr } else { 3064233294Sstas hx509_set_error_string(context, 0, EINVAL, 3065178825Sdfr "Unknown type %d of selection", type); 3066178825Sdfr return EINVAL; 3067178825Sdfr } 3068178825Sdfr 3069178825Sdfr if (peer) { 3070178825Sdfr const heim_oid *keytype = NULL; 3071178825Sdfr 3072178825Sdfr keytype = find_keytype(source); 3073178825Sdfr 3074178825Sdfr for (i = 0; i < peer->len; i++) { 3075178825Sdfr for (j = 0; sig_algs[j]; j++) { 3076178825Sdfr if ((sig_algs[j]->flags & bits) != bits) 3077178825Sdfr continue; 3078233294Sstas if (der_heim_oid_cmp(sig_algs[j]->sig_oid, 3079178825Sdfr &peer->val[i].algorithm) != 0) 3080178825Sdfr continue; 3081233294Sstas if (keytype && sig_algs[j]->key_oid && 3082233294Sstas der_heim_oid_cmp(keytype, sig_algs[j]->key_oid)) 3083178825Sdfr continue; 3084178825Sdfr 3085178825Sdfr /* found one, use that */ 3086178825Sdfr ret = copy_AlgorithmIdentifier(&peer->val[i], selected); 3087178825Sdfr if (ret) 3088178825Sdfr hx509_clear_error_string(context); 3089178825Sdfr return ret; 3090178825Sdfr } 3091178825Sdfr if (bits & SIG_SECRET) { 3092178825Sdfr const struct hx509cipher *cipher; 3093178825Sdfr 3094178825Sdfr cipher = find_cipher_by_oid(&peer->val[i].algorithm); 3095178825Sdfr if (cipher == NULL) 3096178825Sdfr continue; 3097178825Sdfr if (cipher->ai_func == NULL) 3098178825Sdfr continue; 3099178825Sdfr ret = copy_AlgorithmIdentifier(cipher->ai_func(), selected); 3100178825Sdfr if (ret) 3101178825Sdfr hx509_clear_error_string(context); 3102178825Sdfr return ret; 3103178825Sdfr } 3104178825Sdfr } 3105178825Sdfr } 3106178825Sdfr 3107178825Sdfr /* use default */ 3108178825Sdfr ret = copy_AlgorithmIdentifier(def, selected); 3109178825Sdfr if (ret) 3110178825Sdfr hx509_clear_error_string(context); 3111178825Sdfr return ret; 3112178825Sdfr} 3113178825Sdfr 3114178825Sdfrint 3115178825Sdfrhx509_crypto_available(hx509_context context, 3116178825Sdfr int type, 3117178825Sdfr hx509_cert source, 3118178825Sdfr AlgorithmIdentifier **val, 3119178825Sdfr unsigned int *plen) 3120178825Sdfr{ 3121178825Sdfr const heim_oid *keytype = NULL; 3122178825Sdfr unsigned int len, i; 3123178825Sdfr void *ptr; 3124178825Sdfr int bits, ret; 3125178825Sdfr 3126178825Sdfr *val = NULL; 3127178825Sdfr 3128178825Sdfr if (type == HX509_SELECT_ALL) { 3129178825Sdfr bits = SIG_DIGEST | SIG_PUBLIC_SIG | SIG_SECRET; 3130178825Sdfr } else if (type == HX509_SELECT_DIGEST) { 3131178825Sdfr bits = SIG_DIGEST; 3132178825Sdfr } else if (type == HX509_SELECT_PUBLIC_SIG) { 3133178825Sdfr bits = SIG_PUBLIC_SIG; 3134178825Sdfr } else { 3135233294Sstas hx509_set_error_string(context, 0, EINVAL, 3136178825Sdfr "Unknown type %d of available", type); 3137178825Sdfr return EINVAL; 3138178825Sdfr } 3139178825Sdfr 3140178825Sdfr if (source) 3141178825Sdfr keytype = find_keytype(_hx509_cert_private_key(source)); 3142178825Sdfr 3143178825Sdfr len = 0; 3144178825Sdfr for (i = 0; sig_algs[i]; i++) { 3145178825Sdfr if ((sig_algs[i]->flags & bits) == 0) 3146178825Sdfr continue; 3147178825Sdfr if (sig_algs[i]->sig_alg == NULL) 3148178825Sdfr continue; 3149233294Sstas if (keytype && sig_algs[i]->key_oid && 3150233294Sstas der_heim_oid_cmp(sig_algs[i]->key_oid, keytype)) 3151178825Sdfr continue; 3152178825Sdfr 3153178825Sdfr /* found one, add that to the list */ 3154178825Sdfr ptr = realloc(*val, sizeof(**val) * (len + 1)); 3155178825Sdfr if (ptr == NULL) 3156178825Sdfr goto out; 3157178825Sdfr *val = ptr; 3158178825Sdfr 3159233294Sstas ret = copy_AlgorithmIdentifier(sig_algs[i]->sig_alg, &(*val)[len]); 3160178825Sdfr if (ret) 3161178825Sdfr goto out; 3162178825Sdfr len++; 3163178825Sdfr } 3164178825Sdfr 3165178825Sdfr /* Add AES */ 3166178825Sdfr if (bits & SIG_SECRET) { 3167178825Sdfr 3168178825Sdfr for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++) { 3169233294Sstas 3170233294Sstas if (ciphers[i].flags & CIPHER_WEAK) 3171233294Sstas continue; 3172178825Sdfr if (ciphers[i].ai_func == NULL) 3173178825Sdfr continue; 3174178825Sdfr 3175178825Sdfr ptr = realloc(*val, sizeof(**val) * (len + 1)); 3176178825Sdfr if (ptr == NULL) 3177178825Sdfr goto out; 3178178825Sdfr *val = ptr; 3179233294Sstas 3180178825Sdfr ret = copy_AlgorithmIdentifier((ciphers[i].ai_func)(), &(*val)[len]); 3181178825Sdfr if (ret) 3182178825Sdfr goto out; 3183178825Sdfr len++; 3184178825Sdfr } 3185178825Sdfr } 3186178825Sdfr 3187178825Sdfr *plen = len; 3188178825Sdfr return 0; 3189178825Sdfr 3190178825Sdfrout: 3191178825Sdfr for (i = 0; i < len; i++) 3192178825Sdfr free_AlgorithmIdentifier(&(*val)[i]); 3193178825Sdfr free(*val); 3194178825Sdfr *val = NULL; 3195178825Sdfr hx509_set_error_string(context, 0, ENOMEM, "out of memory"); 3196178825Sdfr return ENOMEM; 3197178825Sdfr} 3198178825Sdfr 3199178825Sdfrvoid 3200178825Sdfrhx509_crypto_free_algs(AlgorithmIdentifier *val, 3201178825Sdfr unsigned int len) 3202178825Sdfr{ 3203178825Sdfr unsigned int i; 3204178825Sdfr for (i = 0; i < len; i++) 3205178825Sdfr free_AlgorithmIdentifier(&val[i]); 3206178825Sdfr free(val); 3207233294Sstas} 3208