static int set_private_key(hx509_context context, hx509_cert cert, SecKeyRef pkey) { const SubjectPublicKeyInfo *spi; const Certificate *c; struct kc_rsa *kc; RSAPublicKey pk; hx509_private_key key; size_t size; RSA *rsa; int ret; ret = hx509_private_key_init(&key, NULL, NULL); if (ret) return ret; kc = calloc(1, sizeof(*kc)); if (kc == NULL) _hx509_abort("out of memory"); CFRetain(pkey); kc->pkey = pkey; rsa = RSA_new(); if (rsa == NULL) _hx509_abort("out of memory"); RSA_set_method(rsa, &kc_rsa_pkcs1_method); ret = RSA_set_app_data(rsa, kc); if (ret != 1) _hx509_abort("RSA_set_app_data"); /* * Set up n and e to please RSA_size() */ c = _hx509_get_cert(cert); spi = &c->tbsCertificate.subjectPublicKeyInfo; ret = decode_RSAPublicKey(spi->subjectPublicKey.data, spi->subjectPublicKey.length / 8, &pk, &size); if (ret) { RSA_free(rsa); return 0; } rsa->n = _hx509_int2BN(&pk.modulus); rsa->e = _hx509_int2BN(&pk.publicExponent); free_RSAPublicKey(&pk); kc->keysize = BN_num_bytes(rsa->n); /* * */ hx509_private_key_assign_rsa(key, rsa); _hx509_cert_set_key(cert, key); hx509_private_key_free(&key); return 0; }
static int test_check_crt_components(void) { const int P = 15; const int Q = 17; const int E = 5; const int N = P*Q; const int DP = 3; const int DQ = 13; const int QINV = 8; int ret = 0; RSA *key = NULL; BN_CTX *ctx = NULL; BIGNUM *p = NULL, *q = NULL, *e = NULL; ret = TEST_ptr(key = RSA_new()) && TEST_ptr(ctx = BN_CTX_new()) && TEST_ptr(p = BN_new()) && TEST_ptr(q = BN_new()) && TEST_ptr(e = BN_new()) && TEST_true(BN_set_word(p, P)) && TEST_true(BN_set_word(q, Q)) && TEST_true(BN_set_word(e, E)) && TEST_true(RSA_set0_factors(key, p, q)); if (!ret) { BN_free(p); BN_free(q); goto end; } ret = TEST_true(rsa_sp800_56b_derive_params_from_pq(key, 8, e, ctx)) && TEST_BN_eq_word(key->n, N) && TEST_BN_eq_word(key->dmp1, DP) && TEST_BN_eq_word(key->dmq1, DQ) && TEST_BN_eq_word(key->iqmp, QINV) && TEST_true(rsa_check_crt_components(key, ctx)) /* (a) 1 < dP < (p – 1). */ && TEST_true(BN_set_word(key->dmp1, 1)) && TEST_false(rsa_check_crt_components(key, ctx)) && TEST_true(BN_set_word(key->dmp1, P-1)) && TEST_false(rsa_check_crt_components(key, ctx)) && TEST_true(BN_set_word(key->dmp1, DP)) /* (b) 1 < dQ < (q - 1). */ && TEST_true(BN_set_word(key->dmq1, 1)) && TEST_false(rsa_check_crt_components(key, ctx)) && TEST_true(BN_set_word(key->dmq1, Q-1)) && TEST_false(rsa_check_crt_components(key, ctx)) && TEST_true(BN_set_word(key->dmq1, DQ)) /* (c) 1 < qInv < p */ && TEST_true(BN_set_word(key->iqmp, 1)) && TEST_false(rsa_check_crt_components(key, ctx)) && TEST_true(BN_set_word(key->iqmp, P)) && TEST_false(rsa_check_crt_components(key, ctx)) && TEST_true(BN_set_word(key->iqmp, QINV)) /* (d) 1 = (dP . e) mod (p - 1)*/ && TEST_true(BN_set_word(key->dmp1, DP+1)) && TEST_false(rsa_check_crt_components(key, ctx)) && TEST_true(BN_set_word(key->dmp1, DP)) /* (e) 1 = (dQ . e) mod (q - 1) */ && TEST_true(BN_set_word(key->dmq1, DQ-1)) && TEST_false(rsa_check_crt_components(key, ctx)) && TEST_true(BN_set_word(key->dmq1, DQ)) /* (f) 1 = (qInv . q) mod p */ && TEST_true(BN_set_word(key->iqmp, QINV+1)) && TEST_false(rsa_check_crt_components(key, ctx)) && TEST_true(BN_set_word(key->iqmp, QINV)) /* check defaults are still valid */ && TEST_true(rsa_check_crt_components(key, ctx)); end: BN_free(e); RSA_free(key); BN_CTX_free(ctx); return ret; }
void DtlsTransport::GenerateCertificateAndPrivateKey() { MS_TRACE(); int ret = 0; BIGNUM* bne = nullptr; RSA* rsa_key = nullptr; int num_bits = 1024; X509_NAME* cert_name = nullptr; // Create a big number object. bne = BN_new(); if (!bne) { LOG_OPENSSL_ERROR("BN_new() failed"); goto error; } ret = BN_set_word(bne, RSA_F4); // RSA_F4 == 65537. if (ret == 0) { LOG_OPENSSL_ERROR("BN_set_word() failed"); goto error; } // Generate a RSA key. rsa_key = RSA_new(); if (!rsa_key) { LOG_OPENSSL_ERROR("RSA_new() failed"); goto error; } // This takes some time. ret = RSA_generate_key_ex(rsa_key, num_bits, bne, nullptr); if (ret == 0) { LOG_OPENSSL_ERROR("RSA_generate_key_ex() failed"); goto error; } // Create a private key object (needed to hold the RSA key). DtlsTransport::privateKey = EVP_PKEY_new(); if (!DtlsTransport::privateKey) { LOG_OPENSSL_ERROR("EVP_PKEY_new() failed"); goto error; } ret = EVP_PKEY_assign_RSA(DtlsTransport::privateKey, rsa_key); if (ret == 0) { LOG_OPENSSL_ERROR("EVP_PKEY_assign_RSA() failed"); goto error; } // The RSA key now belongs to the private key, so don't clean it up separately. rsa_key = nullptr; // Create the X509 certificate. DtlsTransport::certificate = X509_new(); if (!DtlsTransport::certificate) { LOG_OPENSSL_ERROR("X509_new() failed"); goto error; } // Set version 3 (note that 0 means version 1). X509_set_version(DtlsTransport::certificate, 2); // Set serial number (avoid default 0). ASN1_INTEGER_set(X509_get_serialNumber(DtlsTransport::certificate), (long)Utils::Crypto::GetRandomUInt(1000000, 9999999)); // Set valid period. X509_gmtime_adj(X509_get_notBefore(DtlsTransport::certificate), -1*60*60*24*365*10); // - 10 years. X509_gmtime_adj(X509_get_notAfter(DtlsTransport::certificate), 60*60*24*365*10); // 10 years. // Set the public key for the certificate using the key. ret = X509_set_pubkey(DtlsTransport::certificate, DtlsTransport::privateKey); if (ret == 0) { LOG_OPENSSL_ERROR("X509_set_pubkey() failed"); goto error; } // Set certificate fields. cert_name = X509_get_subject_name(DtlsTransport::certificate); if (!cert_name) { LOG_OPENSSL_ERROR("X509_get_subject_name() failed"); goto error; } X509_NAME_add_entry_by_txt(cert_name, "O", MBSTRING_ASC, (uint8_t*)MS_APP_NAME, -1, -1, 0); X509_NAME_add_entry_by_txt(cert_name, "CN", MBSTRING_ASC, (uint8_t*)MS_APP_NAME, -1, -1, 0); // It is self-signed so set the issuer name to be the same as the subject. ret = X509_set_issuer_name(DtlsTransport::certificate, cert_name); if (ret == 0) { LOG_OPENSSL_ERROR("X509_set_issuer_name() failed"); goto error; } // Sign the certificate with its own private key. ret = X509_sign(DtlsTransport::certificate, DtlsTransport::privateKey, EVP_sha1()); if (ret == 0) { LOG_OPENSSL_ERROR("X509_sign() failed"); goto error; } // Free stuff and return. BN_free(bne); return; error: if (bne) BN_free(bne); if (rsa_key && !DtlsTransport::privateKey) RSA_free(rsa_key); if (DtlsTransport::privateKey) EVP_PKEY_free(DtlsTransport::privateKey); // NOTE: This also frees the RSA key. if (DtlsTransport::certificate) X509_free(DtlsTransport::certificate); MS_THROW_ERROR("DTLS certificate and private key generation failed"); }
static LUA_FUNCTION(openssl_pkey_new) { EVP_PKEY *pkey = NULL; const char* alg = "rsa"; if (lua_isnoneornil(L, 1) || lua_isstring(L, 1)) { alg = luaL_optstring(L, 1, alg); if (strcasecmp(alg, "rsa") == 0) { int bits = luaL_optint(L, 2, 1024); int e = luaL_optint(L, 3, 65537); RSA* rsa = RSA_new(); BIGNUM *E = BN_new(); BN_set_word(E, e); if (RSA_generate_key_ex(rsa, bits, E, NULL)) { pkey = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pkey, rsa); } else RSA_free(rsa); BN_free(E); } else if (strcasecmp(alg, "dsa") == 0) { int bits = luaL_optint(L, 2, 1024); size_t seed_len = 0; const char* seed = luaL_optlstring(L, 3, NULL, &seed_len); DSA *dsa = DSA_new(); if (DSA_generate_parameters_ex(dsa, bits, (byte*)seed, seed_len, NULL, NULL, NULL) && DSA_generate_key(dsa)) { pkey = EVP_PKEY_new(); EVP_PKEY_assign_DSA(pkey, dsa); } else DSA_free(dsa); } else if (strcasecmp(alg, "dh") == 0) { int bits = luaL_optint(L, 2, 512); int generator = luaL_optint(L, 3, 2); DH* dh = DH_new(); if (DH_generate_parameters_ex(dh, bits, generator, NULL)) { if (DH_generate_key(dh)) { pkey = EVP_PKEY_new(); EVP_PKEY_assign_DH(pkey, dh); } else DH_free(dh); } else DH_free(dh); } #ifndef OPENSSL_NO_EC else if (strcasecmp(alg, "ec") == 0) { EC_KEY *ec = NULL; EC_GROUP *group = openssl_get_ec_group(L, 2, 3, 4); if (!group) luaL_error(L, "failed to get ec_group object"); ec = EC_KEY_new(); if (ec) { EC_KEY_set_group(ec, group); EC_GROUP_free(group); if (EC_KEY_generate_key(ec)) { pkey = EVP_PKEY_new(); EVP_PKEY_assign_EC_KEY(pkey, ec); } else EC_KEY_free(ec); } else EC_GROUP_free(group); } #endif else { luaL_error(L, "not support %s!!!!", alg); } } else if (lua_istable(L, 1)) { lua_getfield(L, 1, "alg"); alg = luaL_optstring(L, -1, alg); lua_pop(L, 1); if (strcasecmp(alg, "rsa") == 0) { pkey = EVP_PKEY_new(); if (pkey) { RSA *rsa = RSA_new(); if (rsa) { OPENSSL_PKEY_SET_BN(1, rsa, n); OPENSSL_PKEY_SET_BN(1, rsa, e); OPENSSL_PKEY_SET_BN(1, rsa, d); OPENSSL_PKEY_SET_BN(1, rsa, p); OPENSSL_PKEY_SET_BN(1, rsa, q); OPENSSL_PKEY_SET_BN(1, rsa, dmp1); OPENSSL_PKEY_SET_BN(1, rsa, dmq1); OPENSSL_PKEY_SET_BN(1, rsa, iqmp); if (rsa->n) { if (!EVP_PKEY_assign_RSA(pkey, rsa)) { EVP_PKEY_free(pkey); pkey = NULL; } } } } } else if (strcasecmp(alg, "dsa") == 0) { pkey = EVP_PKEY_new(); if (pkey) { DSA *dsa = DSA_new(); if (dsa) { OPENSSL_PKEY_SET_BN(-1, dsa, p); OPENSSL_PKEY_SET_BN(-1, dsa, q); OPENSSL_PKEY_SET_BN(-1, dsa, g); OPENSSL_PKEY_SET_BN(-1, dsa, priv_key); OPENSSL_PKEY_SET_BN(-1, dsa, pub_key); if (dsa->p && dsa->q && dsa->g) { if (!dsa->priv_key && !dsa->pub_key) { DSA_generate_key(dsa); } if (!EVP_PKEY_assign_DSA(pkey, dsa)) { EVP_PKEY_free(pkey); pkey = NULL; } } } } } else if (strcasecmp(alg, "dh") == 0) { pkey = EVP_PKEY_new(); if (pkey) { DH *dh = DH_new(); if (dh) { OPENSSL_PKEY_SET_BN(-1, dh, p); OPENSSL_PKEY_SET_BN(-1, dh, g); OPENSSL_PKEY_SET_BN(-1, dh, priv_key); OPENSSL_PKEY_SET_BN(-1, dh, pub_key); if (dh->p && dh->g) { if (!dh->pub_key) { DH_generate_key(dh); } if (!EVP_PKEY_assign_DH(pkey, dh)) { EVP_PKEY_free(pkey); pkey = NULL; } } } } } else if (strcasecmp(alg, "ec") == 0) { BIGNUM *d = NULL; BIGNUM *x = NULL; BIGNUM *y = NULL; BIGNUM *z = NULL; EC_GROUP *group = NULL; lua_getfield(L, -1, "ec_name"); lua_getfield(L, -2, "param_enc"); lua_getfield(L, -3, "conv_form"); group = openssl_get_ec_group(L, -3, -2, -1); lua_pop(L, 3); if (!group) { luaL_error(L, "get openssl.ec_group fail"); } EC_GET_FIELD(d); EC_GET_FIELD(x); EC_GET_FIELD(y); EC_GET_FIELD(z); pkey = EVP_PKEY_new(); if (pkey) { EC_KEY *ec = EC_KEY_new(); if (ec) { EC_KEY_set_group(ec, group); if (d) EC_KEY_set_private_key(ec, d); if (x != NULL && y != NULL) { EC_POINT *pnt = EC_POINT_new(group); if (z == NULL) EC_POINT_set_affine_coordinates_GFp(group, pnt, x, y, NULL); else EC_POINT_set_Jprojective_coordinates_GFp(group, pnt, x, y, z, NULL); EC_KEY_set_public_key(ec, pnt); } if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { EC_KEY_free(ec); EVP_PKEY_free(pkey); pkey = NULL; } if (d && !EC_KEY_check_key(ec)) { EC_KEY_generate_key_part(ec); } } } } } if (pkey) { PUSH_OBJECT(pkey, "openssl.evp_pkey"); return 1; } return 0; }
/* * Decode a string to a key. Return 0 on success. */ int kn_decode_key(struct keynote_deckey *dc, char *key, int keytype) { void *kk = NULL; X509 *px509Cert; EVP_PKEY *pPublicKey; unsigned char *ptr = NULL, *decoded = NULL; int encoding, internalencoding; long len = 0; keynote_errno = 0; if (keytype == KEYNOTE_PRIVATE_KEY) dc->dec_algorithm = keynote_get_private_key_algorithm(key, &encoding, &internalencoding); else dc->dec_algorithm = keynote_get_key_algorithm(key, &encoding, &internalencoding); if (dc->dec_algorithm == KEYNOTE_ALGORITHM_NONE) { if ((dc->dec_key = strdup(key)) == NULL) { keynote_errno = ERROR_MEMORY; return -1; } return 0; } key = strchr(key, ':'); /* Move forward, to the Encoding. We're guaranteed * to have a ':' character, since this is a key */ key++; /* Remove ASCII encoding */ switch (encoding) { case ENCODING_NONE: break; case ENCODING_HEX: len = strlen(key) / 2; if (kn_decode_hex(key, (char **) &decoded) != 0) return -1; ptr = decoded; break; case ENCODING_BASE64: len = strlen(key); if (len % 4) /* Base64 encoding must be a multiple of 4 */ { keynote_errno = ERROR_SYNTAX; return -1; } len = 3 * (len / 4); decoded = calloc(len, sizeof(unsigned char)); ptr = decoded; if (decoded == NULL) { keynote_errno = ERROR_MEMORY; return -1; } if ((len = kn_decode_base64(key, decoded, len)) == -1) return -1; break; case ENCODING_NATIVE: decoded = strdup(key); if (decoded == NULL) { keynote_errno = ERROR_MEMORY; return -1; } len = strlen(key); ptr = decoded; break; default: keynote_errno = ERROR_SYNTAX; return -1; } /* DSA-HEX */ if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_DSA) && (internalencoding == INTERNAL_ENC_ASN1)) { dc->dec_key = DSA_new(); if (dc->dec_key == NULL) { keynote_errno = ERROR_MEMORY; return -1; } kk = dc->dec_key; if (keytype == KEYNOTE_PRIVATE_KEY) { if (d2i_DSAPrivateKey((DSA **) &kk,(const unsigned char **) &decoded, len) == NULL) { free(ptr); DSA_free(kk); keynote_errno = ERROR_SYNTAX; /* Could be a memory error */ return -1; } } else { if (d2i_DSAPublicKey((DSA **) &kk, (const unsigned char **) &decoded, len) == NULL) { free(ptr); DSA_free(kk); keynote_errno = ERROR_SYNTAX; /* Could be a memory error */ return -1; } } free(ptr); return 0; } /* RSA-PKCS1-HEX */ if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_RSA) && (internalencoding == INTERNAL_ENC_PKCS1)) { dc->dec_key = RSA_new(); if (dc->dec_key == NULL) { keynote_errno = ERROR_MEMORY; return -1; } kk = dc->dec_key; if (keytype == KEYNOTE_PRIVATE_KEY) { if (d2i_RSAPrivateKey((RSA **) &kk, (const unsigned char **) &decoded, len) == NULL) { free(ptr); RSA_free(kk); keynote_errno = ERROR_SYNTAX; /* Could be a memory error */ return -1; } if (RSA_blinding_on((RSA *) kk, NULL) != 1) { free(ptr); RSA_free(kk); keynote_errno = ERROR_MEMORY; return -1; } } else { if (d2i_RSAPublicKey((RSA **) &kk, (const unsigned char **) &decoded, len) == NULL) { free(ptr); RSA_free(kk); keynote_errno = ERROR_SYNTAX; /* Could be a memory error */ return -1; } } free(ptr); return 0; } /* X509 Cert */ if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_X509) && (internalencoding == INTERNAL_ENC_ASN1) && (keytype == KEYNOTE_PUBLIC_KEY)) { if ((px509Cert = X509_new()) == NULL) { free(ptr); keynote_errno = ERROR_MEMORY; return -1; } if(d2i_X509(&px509Cert, (const unsigned char **)&decoded, len) == NULL) { free(ptr); X509_free(px509Cert); keynote_errno = ERROR_SYNTAX; return -1; } if ((pPublicKey = X509_get_pubkey(px509Cert)) == NULL) { free(ptr); X509_free(px509Cert); keynote_errno = ERROR_SYNTAX; return -1; } /* RSA-specific */ dc->dec_key = pPublicKey->pkey.rsa; free(ptr); return 0; } /* BINARY keys */ if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_BINARY) && (internalencoding == INTERNAL_ENC_NONE)) { dc->dec_key = calloc(1, sizeof(struct keynote_binary)); if (dc->dec_key == NULL) { keynote_errno = ERROR_MEMORY; return -1; } ((struct keynote_binary *) dc->dec_key)->bn_key = decoded; ((struct keynote_binary *) dc->dec_key)->bn_len = len; return RESULT_TRUE; } /* Add support for more algorithms here */ free(ptr); /* This shouldn't ever be reached really */ keynote_errno = ERROR_SYNTAX; return -1; }
int MAIN(int argc, char **argv) { BN_GENCB cb; # ifndef OPENSSL_NO_ENGINE ENGINE *e = NULL; # endif int ret = 1; int i, num = DEFBITS; long l; const EVP_CIPHER *enc = NULL; unsigned long f4 = RSA_F4; char *outfile = NULL; char *passargout = NULL, *passout = NULL; # ifndef OPENSSL_NO_ENGINE char *engine = NULL; # endif char *inrand = NULL; BIO *out = NULL; BIGNUM *bn = BN_new(); RSA *rsa = NULL; if (!bn) goto err; apps_startup(); BN_GENCB_set(&cb, genrsa_cb, bio_err); if (bio_err == NULL) if ((bio_err = BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); if (!load_config(bio_err, NULL)) goto err; if ((out = BIO_new(BIO_s_file())) == NULL) { BIO_printf(bio_err, "unable to create BIO for output\n"); goto err; } argv++; argc--; for (;;) { if (argc <= 0) break; if (strcmp(*argv, "-out") == 0) { if (--argc < 1) goto bad; outfile = *(++argv); } else if (strcmp(*argv, "-3") == 0) f4 = 3; else if (strcmp(*argv, "-F4") == 0 || strcmp(*argv, "-f4") == 0) f4 = RSA_F4; # ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv, "-engine") == 0) { if (--argc < 1) goto bad; engine = *(++argv); } # endif else if (strcmp(*argv, "-rand") == 0) { if (--argc < 1) goto bad; inrand = *(++argv); } # ifndef OPENSSL_NO_DES else if (strcmp(*argv, "-des") == 0) enc = EVP_des_cbc(); else if (strcmp(*argv, "-des3") == 0) enc = EVP_des_ede3_cbc(); # endif # ifndef OPENSSL_NO_IDEA else if (strcmp(*argv, "-idea") == 0) enc = EVP_idea_cbc(); # endif # ifndef OPENSSL_NO_SEED else if (strcmp(*argv, "-seed") == 0) enc = EVP_seed_cbc(); # endif # ifndef OPENSSL_NO_AES else if (strcmp(*argv, "-aes128") == 0) enc = EVP_aes_128_cbc(); else if (strcmp(*argv, "-aes192") == 0) enc = EVP_aes_192_cbc(); else if (strcmp(*argv, "-aes256") == 0) enc = EVP_aes_256_cbc(); # endif # ifndef OPENSSL_NO_CAMELLIA else if (strcmp(*argv, "-camellia128") == 0) enc = EVP_camellia_128_cbc(); else if (strcmp(*argv, "-camellia192") == 0) enc = EVP_camellia_192_cbc(); else if (strcmp(*argv, "-camellia256") == 0) enc = EVP_camellia_256_cbc(); # endif else if (strcmp(*argv, "-passout") == 0) { if (--argc < 1) goto bad; passargout = *(++argv); } else break; argv++; argc--; } if ((argc >= 1) && ((sscanf(*argv, "%d", &num) == 0) || (num < 0))) { bad: BIO_printf(bio_err, "usage: genrsa [args] [numbits]\n"); BIO_printf(bio_err, " -des encrypt the generated key with DES in cbc mode\n"); BIO_printf(bio_err, " -des3 encrypt the generated key with DES in ede cbc mode (168 bit key)\n"); # ifndef OPENSSL_NO_IDEA BIO_printf(bio_err, " -idea encrypt the generated key with IDEA in cbc mode\n"); # endif # ifndef OPENSSL_NO_SEED BIO_printf(bio_err, " -seed\n"); BIO_printf(bio_err, " encrypt PEM output with cbc seed\n"); # endif # ifndef OPENSSL_NO_AES BIO_printf(bio_err, " -aes128, -aes192, -aes256\n"); BIO_printf(bio_err, " encrypt PEM output with cbc aes\n"); # endif # ifndef OPENSSL_NO_CAMELLIA BIO_printf(bio_err, " -camellia128, -camellia192, -camellia256\n"); BIO_printf(bio_err, " encrypt PEM output with cbc camellia\n"); # endif BIO_printf(bio_err, " -out file output the key to 'file\n"); BIO_printf(bio_err, " -passout arg output file pass phrase source\n"); BIO_printf(bio_err, " -f4 use F4 (0x10001) for the E value\n"); BIO_printf(bio_err, " -3 use 3 for the E value\n"); # ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err, " -engine e use engine e, possibly a hardware device.\n"); # endif BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); BIO_printf(bio_err, " load the file (or the files in the directory) into\n"); BIO_printf(bio_err, " the random number generator\n"); goto err; } ERR_load_crypto_strings(); if (!app_passwd(bio_err, NULL, passargout, NULL, &passout)) { BIO_printf(bio_err, "Error getting password\n"); goto err; } # ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); # endif if (outfile == NULL) { BIO_set_fp(out, stdout, BIO_NOCLOSE); # ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } # endif } else { if (BIO_write_filename(out, outfile) <= 0) { perror(outfile); goto err; } } if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL && !RAND_status()) { BIO_printf(bio_err, "warning, not much extra random data, consider using the -rand option\n"); } if (inrand != NULL) BIO_printf(bio_err, "%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus\n", num); # ifdef OPENSSL_NO_ENGINE rsa = RSA_new(); # else rsa = RSA_new_method(e); # endif if (!rsa) goto err; if (!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, &cb)) goto err; app_RAND_write_file(NULL, bio_err); /* * We need to do the following for when the base number size is < long, * esp windows 3.1 :-(. */ l = 0L; for (i = 0; i < rsa->e->top; i++) { # ifndef SIXTY_FOUR_BIT l <<= BN_BITS4; l <<= BN_BITS4; # endif l += rsa->e->d[i]; } BIO_printf(bio_err, "e is %ld (0x%lX)\n", l, l); { PW_CB_DATA cb_data; cb_data.password = passout; cb_data.prompt_info = outfile; if (!PEM_write_bio_RSAPrivateKey(out, rsa, enc, NULL, 0, (pem_password_cb *)password_callback, &cb_data)) goto err; } ret = 0; err: if (bn) BN_free(bn); if (rsa) RSA_free(rsa); if (out) BIO_free_all(out); if (passout) OPENSSL_free(passout); if (ret != 0) ERR_print_errors(bio_err); apps_shutdown(); OPENSSL_EXIT(ret); }
soter_status_t soter_rsa_priv_key_to_engine_specific(const soter_container_hdr_t *key, size_t key_length, soter_engine_specific_rsa_key_t **engine_key) { int rsa_mod_size; RSA *rsa; EVP_PKEY *pkey = (EVP_PKEY *)(*engine_key); const uint32_t *pub_exp; const unsigned char *curr_bn = (const unsigned char *)(key + 1); if (key_length != ntohl(key->size)) { return SOTER_INVALID_PARAMETER; } /* Validate tag */ if (memcmp(key->tag, RSA_PRIV_KEY_PREF, strlen(RSA_PRIV_KEY_PREF))) { return SOTER_INVALID_PARAMETER; } if (SOTER_SUCCESS != soter_verify_container_checksum(key)) { return SOTER_DATA_CORRUPT; } switch (key->tag[3]) { case '1': rsa_mod_size = 128; break; case '2': rsa_mod_size = 256; break; case '4': rsa_mod_size = 512; break; case '8': rsa_mod_size = 1024; break; default: return SOTER_INVALID_PARAMETER; } if (key_length < rsa_priv_key_size(rsa_mod_size)) { return SOTER_INVALID_PARAMETER; } pub_exp = (const uint32_t *)(curr_bn + ((rsa_mod_size * 4) + (rsa_mod_size / 2)));; switch (ntohl(*pub_exp)) { case RSA_3: case RSA_F4: break; default: return SOTER_INVALID_PARAMETER; } rsa = RSA_new(); if (!rsa) { return SOTER_NO_MEMORY; } rsa->e = BN_new(); if (!(rsa->e)) { RSA_free(rsa); return SOTER_NO_MEMORY; } if (!BN_set_word(rsa->e, ntohl(*pub_exp))) { RSA_free(rsa); return SOTER_FAIL; } /* Private exponent */ rsa->d = BN_new(); if (!(rsa->d)) { RSA_free(rsa); return SOTER_NO_MEMORY; } if (!BN_bin2bn(curr_bn, rsa_mod_size, rsa->d)) { RSA_free(rsa); return SOTER_FAIL; } curr_bn += rsa_mod_size; /* p */ rsa->p = BN_new(); if (!(rsa->p)) { RSA_free(rsa); return SOTER_NO_MEMORY; } if (!BN_bin2bn(curr_bn, rsa_mod_size / 2, rsa->p)) { RSA_free(rsa); return SOTER_FAIL; } curr_bn += rsa_mod_size / 2; /* q */ rsa->q = BN_new(); if (!(rsa->q)) { RSA_free(rsa); return SOTER_NO_MEMORY; } if (!BN_bin2bn(curr_bn, rsa_mod_size / 2, rsa->q)) { RSA_free(rsa); return SOTER_FAIL; } curr_bn += rsa_mod_size / 2; /* dp */ rsa->dmp1 = BN_new(); if (!(rsa->dmp1)) { RSA_free(rsa); return SOTER_NO_MEMORY; } if (!BN_bin2bn(curr_bn, rsa_mod_size / 2, rsa->dmp1)) { RSA_free(rsa); return SOTER_FAIL; } curr_bn += rsa_mod_size / 2; /* dq */ rsa->dmq1 = BN_new(); if (!(rsa->dmq1)) { RSA_free(rsa); return SOTER_NO_MEMORY; } if (!BN_bin2bn(curr_bn, rsa_mod_size / 2, rsa->dmq1)) { RSA_free(rsa); return SOTER_FAIL; } curr_bn += rsa_mod_size / 2; /* qp */ rsa->iqmp = BN_new(); if (!(rsa->iqmp)) { RSA_free(rsa); return SOTER_NO_MEMORY; } if (!BN_bin2bn(curr_bn, rsa_mod_size / 2, rsa->iqmp)) { RSA_free(rsa); return SOTER_FAIL; } curr_bn += rsa_mod_size / 2; /* modulus */ rsa->n = BN_new(); if (!(rsa->n)) { RSA_free(rsa); return SOTER_NO_MEMORY; } if (!BN_bin2bn(curr_bn, rsa_mod_size, rsa->n)) { RSA_free(rsa); return SOTER_FAIL; } /* If at least one CRT parameter is zero, free them */ if (BN_is_zero(rsa->p) || BN_is_zero(rsa->q) || BN_is_zero(rsa->dmp1) || BN_is_zero(rsa->dmq1) || BN_is_zero(rsa->iqmp)) { BN_free(rsa->p); rsa->p = NULL; BN_free(rsa->q); rsa->q = NULL; BN_free(rsa->dmp1); rsa->dmp1 = NULL; BN_free(rsa->dmq1); rsa->dmq1 = NULL; BN_free(rsa->iqmp); rsa->iqmp = NULL; } if (!EVP_PKEY_assign_RSA(pkey, rsa)) { RSA_free(rsa); return SOTER_FAIL; } /* EVP_PKEY_assign_RSA does not increment the reference count, so no need to free RSA object */ return SOTER_SUCCESS; }
void openssl_rsa_crypt() { RSA *r; BIO *b; BIGNUM *bne; unsigned int len; int size, elen, dlen; unsigned char inputs[COMM_LEN] = "rsa crypt"; unsigned char tmps[MAX1_LEN], outputs[MAX1_LEN]; memset(tmps, 0, sizeof(tmps)); memset(outputs, 0, sizeof(outputs)); printf("\nRSA generate key:\n"); bne = BN_new(); BN_set_word(bne, RSA_3); r = RSA_new(); RSA_generate_key_ex(r, MAX1_LEN, bne, NULL); RSA_print_fp(stdout, r, 11); b = BIO_new_file("/tmp/rsa.key", "w"); i2d_RSAPrivateKey_bio(b, r); BIO_free(b); elen = RSA_private_encrypt(RSA_size(r) - 11, inputs, outputs, r, RSA_PKCS1_PADDING); dlen = RSA_public_decrypt(elen, outputs, tmps, r, RSA_PKCS1_PADDING); if (elen <= 0 || dlen <= 0 || memcmp(inputs, tmps, RSA_size(r) - 11)) { printf("RSA_private_encrypt error!\n"); RSA_free(r); return; } printf("RSA_private_encrypt(%s) = ", inputs); for (size = 0; size < elen; size++) printf("%02x", outputs[size]); printf("\n"); memset(outputs, 0, sizeof(outputs)); elen = RSA_public_encrypt(RSA_size(r) - 11, inputs, outputs, r, RSA_PKCS1_PADDING); dlen = RSA_private_decrypt(elen, outputs, tmps, r, RSA_PKCS1_PADDING); if (elen <= 0 || dlen <= 0 || memcmp(inputs, tmps, RSA_size(r) - 11)) { printf("RSA_public_encrypt error!\n"); RSA_free(r); return; } printf("RSA_public_encrypt(%s) = ", inputs); for (size = 0; size < elen; size++) printf("%02x", outputs[size]); printf("\n"); memset(outputs, 0, sizeof(outputs)); RSA_sign(NID_md5_sha1, inputs, 36, outputs, &len, r); printf("RSA_sign(%s) = ", inputs); for (size = 0; size < len; size++) printf("%02x", outputs[size]); printf("\n"); memset(tmps, 0, sizeof(tmps)); RSA_verify(NID_md5_sha1, inputs, 36, outputs, len, r); printf("RSA_verify("); for (size = 0; size < len; size++) printf("%02x", outputs[size]); printf(") = %s\n", inputs); RSA_free(r); }
static int AuthenticationDialogue(ServerConnectionState *conn, char *recvbuffer, int recvlen) { char in[CF_BUFSIZE], *out, *decrypted_nonce; BIGNUM *counter_challenge = NULL; unsigned char digest[EVP_MAX_MD_SIZE + 1] = { 0 }; unsigned int crypt_len, nonce_len = 0, encrypted_len = 0; char sauth[10], iscrypt = 'n', enterprise_field = 'c'; int len_n = 0, len_e = 0, keylen, session_size; unsigned long err; RSA *newkey; int digestLen = 0; HashMethod digestType; if ((PRIVKEY == NULL) || (PUBKEY == NULL)) { Log(LOG_LEVEL_ERR, "No public/private key pair exists, create one with cf-key"); return false; } if (FIPS_MODE) { digestType = CF_DEFAULT_DIGEST; digestLen = CF_DEFAULT_DIGEST_LEN; } else { digestType = HASH_METHOD_MD5; digestLen = CF_MD5_LEN; } /* proposition C1 */ /* Opening string is a challenge from the client (some agent) */ sauth[0] = '\0'; sscanf(recvbuffer, "%s %c %u %u %c", sauth, &iscrypt, &crypt_len, &nonce_len, &enterprise_field); if ((crypt_len == 0) || (nonce_len == 0) || (strlen(sauth) == 0)) { Log(LOG_LEVEL_INFO, "Protocol format error in authentation from IP %s", conn->hostname); return false; } if (nonce_len > CF_NONCELEN * 2) { Log(LOG_LEVEL_INFO, "Protocol deviant authentication nonce from %s", conn->hostname); return false; } if (crypt_len > 2 * CF_NONCELEN) { Log(LOG_LEVEL_INFO, "Protocol abuse in unlikely cipher from %s", conn->hostname); return false; } /* Check there is no attempt to read past the end of the received input */ if (recvbuffer + CF_RSA_PROTO_OFFSET + nonce_len > recvbuffer + recvlen) { Log(LOG_LEVEL_INFO, "Protocol consistency error in authentication from %s", conn->hostname); return false; } if ((strcmp(sauth, "SAUTH") != 0) || (nonce_len == 0) || (crypt_len == 0)) { Log(LOG_LEVEL_INFO, "Protocol error in RSA authentication from IP '%s'", conn->hostname); return false; } Log(LOG_LEVEL_DEBUG, "Challenge encryption = %c, nonce = %d, buf = %d", iscrypt, nonce_len, crypt_len); decrypted_nonce = xmalloc(crypt_len); if (iscrypt == 'y') { if (RSA_private_decrypt (crypt_len, recvbuffer + CF_RSA_PROTO_OFFSET, decrypted_nonce, PRIVKEY, RSA_PKCS1_PADDING) <= 0) { err = ERR_get_error(); Log(LOG_LEVEL_ERR, "Private decrypt failed = '%s'. Probably the client has the wrong public key for this server", ERR_reason_error_string(err)); free(decrypted_nonce); return false; } } else { if (nonce_len > crypt_len) { Log(LOG_LEVEL_ERR, "Illegal challenge"); free(decrypted_nonce); return false; } memcpy(decrypted_nonce, recvbuffer + CF_RSA_PROTO_OFFSET, nonce_len); } /* Client's ID is now established by key or trusted, reply with digest */ HashString(decrypted_nonce, nonce_len, digest, digestType); free(decrypted_nonce); /* Get the public key from the client */ newkey = RSA_new(); /* proposition C2 */ if ((len_n = ReceiveTransaction(conn->conn_info, recvbuffer, NULL)) == -1) { Log(LOG_LEVEL_INFO, "Protocol error 1 in RSA authentation from IP %s", conn->hostname); RSA_free(newkey); return false; } if (len_n == 0) { Log(LOG_LEVEL_INFO, "Protocol error 2 in RSA authentation from IP %s", conn->hostname); RSA_free(newkey); return false; } if ((newkey->n = BN_mpi2bn(recvbuffer, len_n, NULL)) == NULL) { err = ERR_get_error(); Log(LOG_LEVEL_ERR, "Private decrypt failed = %s", ERR_reason_error_string(err)); RSA_free(newkey); return false; } /* proposition C3 */ if ((len_e = ReceiveTransaction(conn->conn_info, recvbuffer, NULL)) == -1) { Log(LOG_LEVEL_INFO, "Protocol error 3 in RSA authentation from IP %s", conn->hostname); RSA_free(newkey); return false; } if (len_e == 0) { Log(LOG_LEVEL_INFO, "Protocol error 4 in RSA authentation from IP %s", conn->hostname); RSA_free(newkey); return false; } if ((newkey->e = BN_mpi2bn(recvbuffer, len_e, NULL)) == NULL) { err = ERR_get_error(); Log(LOG_LEVEL_ERR, "Private decrypt failed = %s", ERR_reason_error_string(err)); RSA_free(newkey); return false; } /* Compute and store hash of the client's public key. */ Key *key = KeyNew(newkey, CF_DEFAULT_DIGEST); ConnectionInfoSetKey(conn->conn_info, key); Log(LOG_LEVEL_VERBOSE, "Public key identity of host '%s' is '%s'", conn->ipaddr, KeyPrintableHash(ConnectionInfoKey(conn->conn_info))); LastSaw1(conn->ipaddr, KeyPrintableHash(ConnectionInfoKey(conn->conn_info)), LAST_SEEN_ROLE_ACCEPT); if (!CheckStoreKey(conn, newkey)) /* conceals proposition S1 */ { return false; } /* Reply with digest of original challenge */ /* proposition S2 */ SendTransaction(conn->conn_info, digest, digestLen, CF_DONE); /* Send counter challenge to be sure this is a live session */ counter_challenge = BN_new(); if (counter_challenge == NULL) { Log(LOG_LEVEL_ERR, "Cannot allocate BIGNUM structure for counter challenge"); return false; } BN_rand(counter_challenge, CF_NONCELEN, 0, 0); nonce_len = BN_bn2mpi(counter_challenge, in); // hash the challenge from the client HashString(in, nonce_len, digest, digestType); encrypted_len = RSA_size(newkey); /* encryption buffer is always the same size as n */ out = xmalloc(encrypted_len + 1); if (RSA_public_encrypt(nonce_len, in, out, newkey, RSA_PKCS1_PADDING) <= 0) { err = ERR_get_error(); Log(LOG_LEVEL_ERR, "Public encryption failed = %s", ERR_reason_error_string(err)); free(out); return false; } /* proposition S3 */ SendTransaction(conn->conn_info, out, encrypted_len, CF_DONE); /* if the client doesn't have our public key, send it */ if (iscrypt != 'y') { /* proposition S4 - conditional */ memset(in, 0, CF_BUFSIZE); len_n = BN_bn2mpi(PUBKEY->n, in); SendTransaction(conn->conn_info, in, len_n, CF_DONE); /* proposition S5 - conditional */ memset(in, 0, CF_BUFSIZE); len_e = BN_bn2mpi(PUBKEY->e, in); SendTransaction(conn->conn_info, in, len_e, CF_DONE); } /* Receive reply to counter_challenge */ /* proposition C4 */ memset(in, 0, CF_BUFSIZE); if (ReceiveTransaction(conn->conn_info, in, NULL) == -1) { BN_free(counter_challenge); free(out); return false; } if (HashesMatch(digest, in, digestType)) /* replay / piggy in the middle attack ? */ { Log(LOG_LEVEL_VERBOSE, "Authentication of client %s/%s achieved", conn->hostname, conn->ipaddr); } else { BN_free(counter_challenge); free(out); Log(LOG_LEVEL_INFO, "Challenge response from client %s was incorrect - ID false?", conn->ipaddr); return false; } /* Receive random session key,... */ /* proposition C5 */ memset(in, 0, CF_BUFSIZE); if ((keylen = ReceiveTransaction(conn->conn_info, in, NULL)) == -1) { BN_free(counter_challenge); free(out); return false; } if (keylen > CF_BUFSIZE / 2) { BN_free(counter_challenge); free(out); Log(LOG_LEVEL_INFO, "Session key length received from %s is too long", conn->ipaddr); return false; } session_size = CfSessionKeySize(enterprise_field); conn->session_key = xmalloc(session_size); conn->encryption_type = enterprise_field; Log(LOG_LEVEL_VERBOSE, "Receiving session key from client (size=%d)...", keylen); Log(LOG_LEVEL_DEBUG, "keylen = %d, session_size = %d", keylen, session_size); if (keylen == CF_BLOWFISHSIZE) /* Support the old non-ecnrypted for upgrade */ { memcpy(conn->session_key, in, session_size); } else { /* New protocol encrypted */ if (RSA_private_decrypt(keylen, in, out, PRIVKEY, RSA_PKCS1_PADDING) <= 0) { err = ERR_get_error(); Log(LOG_LEVEL_ERR, "Private decrypt failed = %s", ERR_reason_error_string(err)); BN_free(counter_challenge); free(out); return false; } memcpy(conn->session_key, out, session_size); } BN_free(counter_challenge); free(out); return true; }
RSA *RSA_generate_key(int bits, unsigned long e_value, void (*callback)(int,int,void *), void *cb_arg) { RSA *rsa=NULL; BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp; int bitsp,bitsq,ok= -1,n=0; unsigned i; BN_CTX *ctx=NULL,*ctx2=NULL; ctx=BN_CTX_new(); if (ctx == NULL) goto err; ctx2=BN_CTX_new(); if (ctx2 == NULL) goto err; BN_CTX_start(ctx); r0 = BN_CTX_get(ctx); r1 = BN_CTX_get(ctx); r2 = BN_CTX_get(ctx); r3 = BN_CTX_get(ctx); if (r3 == NULL) goto err; bitsp=(bits+1)/2; bitsq=bits-bitsp; rsa=RSA_new(); if (rsa == NULL) goto err; /* set e */ rsa->e=BN_new(); if (rsa->e == NULL) goto err; #if 1 /* The problem is when building with 8, 16, or 32 BN_ULONG, * unsigned long can be larger */ for (i=0; i<sizeof(unsigned long)*8; i++) { if (e_value & (((unsigned long)1)<<i)) BN_set_bit(rsa->e,i); } #else if (!BN_set_word(rsa->e,e_value)) goto err; #endif /* generate p and q */ for (;;) { rsa->p=BN_generate_prime(NULL,bitsp,0,NULL,NULL,callback,cb_arg); if (rsa->p == NULL) goto err; if (!BN_sub(r2,rsa->p,BN_value_one())) goto err; if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err; if (BN_is_one(r1)) break; if (callback != NULL) callback(2,n++,cb_arg); BN_free(rsa->p); } if (callback != NULL) callback(3,0,cb_arg); for (;;) { rsa->q=BN_generate_prime(NULL,bitsq,0,NULL,NULL,callback,cb_arg); if (rsa->q == NULL) goto err; if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err; if (BN_is_one(r1) && (BN_cmp(rsa->p,rsa->q) != 0)) break; if (callback != NULL) callback(2,n++,cb_arg); BN_free(rsa->q); } if (callback != NULL) callback(3,1,cb_arg); if (BN_cmp(rsa->p,rsa->q) < 0) { tmp=rsa->p; rsa->p=rsa->q; rsa->q=tmp; } /* calculate n */ rsa->n=BN_new(); if (rsa->n == NULL) goto err; if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err; /* calculate d */ if (!BN_sub(r1,rsa->p,BN_value_one())) goto err; /* p-1 */ if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; /* q-1 */ if (!BN_mul(r0,r1,r2,ctx)) goto err; /* (p-1)(q-1) */ /* should not be needed, since gcd(p-1,e) == 1 and gcd(q-1,e) == 1 */ /* for (;;) { if (!BN_gcd(r3,r0,rsa->e,ctx)) goto err; if (BN_is_one(r3)) break; if (1) { if (!BN_add_word(rsa->e,2L)) goto err; continue; } RSAerr(RSA_F_RSA_GENERATE_KEY,RSA_R_BAD_E_VALUE); goto err; } */ rsa->d=BN_mod_inverse(NULL,rsa->e,r0,ctx2); /* d */ if (rsa->d == NULL) goto err; /* calculate d mod (p-1) */ rsa->dmp1=BN_new(); if (rsa->dmp1 == NULL) goto err; if (!BN_mod(rsa->dmp1,rsa->d,r1,ctx)) goto err; /* calculate d mod (q-1) */ rsa->dmq1=BN_new(); if (rsa->dmq1 == NULL) goto err; if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx)) goto err; /* calculate inverse of q mod p */ rsa->iqmp=BN_mod_inverse(NULL,rsa->q,rsa->p,ctx2); if (rsa->iqmp == NULL) goto err; ok=1; err: if (ok == -1) { RSAerr(RSA_F_RSA_GENERATE_KEY,ERR_LIB_BN); ok=0; } BN_CTX_end(ctx); BN_CTX_free(ctx); BN_CTX_free(ctx2); if (!ok) { if (rsa != NULL) RSA_free(rsa); return(NULL); } else return(rsa); }
void openssl_x509_crl() { RSA *r; BIO *bp; int len; FILE *fp; BIGNUM *bne; X509_CRL *crl; EVP_PKEY *pkey; X509_NAME *issuer; ASN1_INTEGER *serial; X509_REVOKED *revoked; ASN1_TIME *lastUpdate, *nextUpdate, *rvTime; unsigned char *buf, *p, tmp[MAX1_LEN] = "crl cert"; printf("\nX509_CRL info:\n"); bne = BN_new(); BN_set_word(bne, RSA_3); r = RSA_new(); RSA_generate_key_ex(r, MAX1_LEN, bne, NULL); pkey = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pkey, r); crl = X509_CRL_new(); X509_CRL_set_version(crl, 3); issuer = X509_NAME_new(); X509_NAME_add_entry_by_NID(issuer, NID_commonName, V_ASN1_PRINTABLESTRING, tmp, 10, -1, 0); X509_CRL_set_issuer_name(crl, issuer); lastUpdate = ASN1_TIME_new(); ASN1_TIME_set(lastUpdate, time(NULL)); X509_CRL_set_lastUpdate(crl, lastUpdate); nextUpdate = ASN1_TIME_new(); ASN1_TIME_set(nextUpdate, time(NULL) + 1280); X509_CRL_set_nextUpdate(crl, nextUpdate); revoked = X509_REVOKED_new(); serial = ASN1_INTEGER_new(); ASN1_INTEGER_set(serial, 1280); X509_REVOKED_set_serialNumber(revoked, serial); rvTime = ASN1_TIME_new(); ASN1_TIME_set(rvTime, time(NULL) + 2000); X509_CRL_set_nextUpdate(crl, rvTime); X509_REVOKED_set_revocationDate(revoked, rvTime); X509_CRL_add0_revoked(crl, revoked); X509_CRL_sort(crl); X509_CRL_sign(crl, pkey, EVP_md5()); bp = BIO_new(BIO_s_file()); BIO_set_fp(bp, stdout, BIO_NOCLOSE); X509_CRL_print(bp, crl); len = i2d_X509_CRL(crl, NULL); buf = (unsigned char *)malloc(len + 10); p = buf; len = i2d_X509_CRL(crl, &p); fp = fopen("/tmp/crl.crl", "wb"); fwrite(buf, 1, len, fp); fclose(fp); free(buf); BIO_free(bp); X509_CRL_free(crl); }
RSA * sldns_key_buf2rsa_raw(unsigned char* key, size_t len) { uint16_t offset; uint16_t exp; uint16_t int16; RSA *rsa; BIGNUM *modulus; BIGNUM *exponent; if (len == 0) return NULL; if (key[0] == 0) { if(len < 3) return NULL; memmove(&int16, key+1, 2); exp = ntohs(int16); offset = 3; } else { exp = key[0]; offset = 1; } /* key length at least one */ if(len < (size_t)offset + exp + 1) return NULL; /* Exponent */ exponent = BN_new(); if(!exponent) return NULL; (void) BN_bin2bn(key+offset, (int)exp, exponent); offset += exp; /* Modulus */ modulus = BN_new(); if(!modulus) { BN_free(exponent); return NULL; } /* length of the buffer must match the key length! */ (void) BN_bin2bn(key+offset, (int)(len - offset), modulus); rsa = RSA_new(); if(!rsa) { BN_free(exponent); BN_free(modulus); return NULL; } #if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL) #ifndef S_SPLINT_S rsa->n = modulus; rsa->e = exponent; #endif /* splint */ #else /* OPENSSL_VERSION_NUMBER */ if (!RSA_set0_key(rsa, modulus, exponent, NULL)) { BN_free(exponent); BN_free(modulus); RSA_free(rsa); return NULL; } #endif return rsa; }
int AuthenticateAgent(AgentConnection *conn, bool trust_key) { char sendbuffer[CF_EXPANDSIZE], in[CF_BUFSIZE], *out, *decrypted_cchall; BIGNUM *nonce_challenge, *bn = NULL; unsigned char digest[EVP_MAX_MD_SIZE]; int encrypted_len, nonce_len = 0, len, session_size; bool need_to_implicitly_trust_server; char enterprise_field = 'c'; RSA *server_pubkey = NULL; if ((PUBKEY == NULL) || (PRIVKEY == NULL)) { /* Try once more to load the keys, maybe the system is converging. */ LoadSecretKeys(); if ((PUBKEY == NULL) || (PRIVKEY == NULL)) { char *pubkeyfile = PublicKeyFile(GetWorkDir()); Log(LOG_LEVEL_ERR, "No public/private key pair found at: %s", pubkeyfile); free(pubkeyfile); return false; } } enterprise_field = CfEnterpriseOptions(); session_size = CfSessionKeySize(enterprise_field); /* Generate a random challenge to authenticate the server */ nonce_challenge = BN_new(); if (nonce_challenge == NULL) { Log(LOG_LEVEL_ERR, "Cannot allocate BIGNUM structure for server challenge"); return false; } BN_rand(nonce_challenge, CF_NONCELEN, 0, 0); nonce_len = BN_bn2mpi(nonce_challenge, in); if (FIPS_MODE) { HashString(in, nonce_len, digest, CF_DEFAULT_DIGEST); } else { HashString(in, nonce_len, digest, HASH_METHOD_MD5); } /* We assume that the server bound to the remote socket is the official one i.e. = root's */ /* Ask the server to send us the public key if we don't have it. */ if ((server_pubkey = HavePublicKeyByIP(conn->username, conn->remoteip))) { need_to_implicitly_trust_server = false; encrypted_len = RSA_size(server_pubkey); } else { need_to_implicitly_trust_server = true; encrypted_len = nonce_len; } // Server pubkey is what we want to has as a unique ID snprintf(sendbuffer, sizeof(sendbuffer), "SAUTH %c %d %d %c", need_to_implicitly_trust_server ? 'n': 'y', encrypted_len, nonce_len, enterprise_field); out = xmalloc(encrypted_len); if (server_pubkey != NULL) { if (RSA_public_encrypt(nonce_len, in, out, server_pubkey, RSA_PKCS1_PADDING) <= 0) { Log(LOG_LEVEL_ERR, "Public encryption failed. (RSA_public_encrypt: %s)", CryptoLastErrorString()); free(out); RSA_free(server_pubkey); return false; } memcpy(sendbuffer + CF_RSA_PROTO_OFFSET, out, encrypted_len); } else { memcpy(sendbuffer + CF_RSA_PROTO_OFFSET, in, nonce_len); } /* proposition C1 - Send challenge / nonce */ SendTransaction(conn->conn_info, sendbuffer, CF_RSA_PROTO_OFFSET + encrypted_len, CF_DONE); BN_free(bn); BN_free(nonce_challenge); free(out); /*Send the public key - we don't know if server has it */ /* proposition C2 */ memset(sendbuffer, 0, CF_EXPANDSIZE); len = BN_bn2mpi(PUBKEY->n, sendbuffer); SendTransaction(conn->conn_info, sendbuffer, len, CF_DONE); /* No need to encrypt the public key ... */ /* proposition C3 */ memset(sendbuffer, 0, CF_EXPANDSIZE); len = BN_bn2mpi(PUBKEY->e, sendbuffer); SendTransaction(conn->conn_info, sendbuffer, len, CF_DONE); /* check reply about public key - server can break conn_info here */ /* proposition S1 */ memset(in, 0, CF_BUFSIZE); if (ReceiveTransaction(conn->conn_info, in, NULL) == -1) { Log(LOG_LEVEL_ERR, "Protocol transaction broken off (1). (ReceiveTransaction: %s)", GetErrorStr()); RSA_free(server_pubkey); return false; } if (BadProtoReply(in)) { Log(LOG_LEVEL_ERR, "Bad protocol reply: %s", in); RSA_free(server_pubkey); return false; } /* Get challenge response - should be CF_DEFAULT_DIGEST of challenge */ /* proposition S2 */ memset(in, 0, CF_BUFSIZE); if (ReceiveTransaction(conn->conn_info, in, NULL) == -1) { Log(LOG_LEVEL_ERR, "Protocol transaction broken off (2). (ReceiveTransaction: %s)", GetErrorStr()); RSA_free(server_pubkey); return false; } /* Check if challenge reply was correct */ if ((HashesMatch(digest, in, CF_DEFAULT_DIGEST)) || (HashesMatch(digest, in, HASH_METHOD_MD5))) // Legacy { if (need_to_implicitly_trust_server == false) { /* The IP was found in lastseen. */ Log(LOG_LEVEL_VERBOSE, ".....................[.h.a.i.l.]................................."); Log(LOG_LEVEL_VERBOSE, "Strong authentication of server '%s' connection confirmed", conn->this_server); } else /* IP was not found in lastseen */ { if (trust_key) { Log(LOG_LEVEL_VERBOSE, "Trusting server identity, promise to accept key from '%s' = '%s'", conn->this_server, conn->remoteip); } else { Log(LOG_LEVEL_ERR, "Not authorized to trust public key of server '%s' (trustkey = false)", conn->this_server); RSA_free(server_pubkey); return false; } } } else { Log(LOG_LEVEL_ERR, "Challenge response from server '%s/%s' was incorrect", conn->this_server, conn->remoteip); RSA_free(server_pubkey); return false; } /* Receive counter challenge from server */ /* proposition S3 */ memset(in, 0, CF_BUFSIZE); encrypted_len = ReceiveTransaction(conn->conn_info, in, NULL); if (encrypted_len <= 0) { Log(LOG_LEVEL_ERR, "Protocol transaction sent illegal cipher length"); RSA_free(server_pubkey); return false; } decrypted_cchall = xmalloc(encrypted_len); if (RSA_private_decrypt(encrypted_len, in, decrypted_cchall, PRIVKEY, RSA_PKCS1_PADDING) <= 0) { Log(LOG_LEVEL_ERR, "Private decrypt failed, abandoning. (RSA_private_decrypt: %s)", CryptoLastErrorString()); RSA_free(server_pubkey); return false; } /* proposition C4 */ if (FIPS_MODE) { HashString(decrypted_cchall, nonce_len, digest, CF_DEFAULT_DIGEST); } else { HashString(decrypted_cchall, nonce_len, digest, HASH_METHOD_MD5); } if (FIPS_MODE) { SendTransaction(conn->conn_info, digest, CF_DEFAULT_DIGEST_LEN, CF_DONE); } else { SendTransaction(conn->conn_info, digest, CF_MD5_LEN, CF_DONE); } free(decrypted_cchall); /* If we don't have the server's public key, it will be sent */ if (server_pubkey == NULL) { RSA *newkey = RSA_new(); Log(LOG_LEVEL_VERBOSE, "Collecting public key from server!"); /* proposition S4 - conditional */ if ((len = ReceiveTransaction(conn->conn_info, in, NULL)) <= 0) { Log(LOG_LEVEL_ERR, "Protocol error in RSA authentation from IP '%s'", conn->this_server); return false; } if ((newkey->n = BN_mpi2bn(in, len, NULL)) == NULL) { Log(LOG_LEVEL_ERR, "Private key decrypt failed. (BN_mpi2bn: %s)", CryptoLastErrorString()); RSA_free(newkey); return false; } /* proposition S5 - conditional */ if ((len = ReceiveTransaction(conn->conn_info, in, NULL)) <= 0) { Log(LOG_LEVEL_INFO, "Protocol error in RSA authentation from IP '%s'", conn->this_server); RSA_free(newkey); return false; } if ((newkey->e = BN_mpi2bn(in, len, NULL)) == NULL) { Log(LOG_LEVEL_ERR, "Public key decrypt failed. (BN_mpi2bn: %s)", CryptoLastErrorString()); RSA_free(newkey); return false; } server_pubkey = RSAPublicKey_dup(newkey); RSA_free(newkey); } assert(server_pubkey != NULL); /* proposition C5 */ if (!SetSessionKey(conn)) { Log(LOG_LEVEL_ERR, "Unable to set session key"); return false; } if (conn->session_key == NULL) { Log(LOG_LEVEL_ERR, "A random session key could not be established"); RSA_free(server_pubkey); return false; } encrypted_len = RSA_size(server_pubkey); out = xmalloc(encrypted_len); if (RSA_public_encrypt(session_size, conn->session_key, out, server_pubkey, RSA_PKCS1_PADDING) <= 0) { Log(LOG_LEVEL_ERR, "Public encryption failed. (RSA_public_encrypt: %s)", CryptoLastErrorString()); free(out); RSA_free(server_pubkey); return false; } SendTransaction(conn->conn_info, out, encrypted_len, CF_DONE); Key *key = KeyNew(server_pubkey, CF_DEFAULT_DIGEST); conn->conn_info->remote_key = key; Log(LOG_LEVEL_VERBOSE, "Public key identity of host '%s' is: %s", conn->remoteip, KeyPrintableHash(conn->conn_info->remote_key)); SavePublicKey(conn->username, KeyPrintableHash(conn->conn_info->remote_key), server_pubkey); unsigned int length = 0; LastSaw(conn->remoteip, KeyBinaryHash(conn->conn_info->remote_key, &length), LAST_SEEN_ROLE_CONNECT); free(out); return true; }
/* Generate a public/private RSA keypair, and ask for a file to store them in. */ static bool keygen(int bits) { BIGNUM *e = NULL; RSA *rsa_key; FILE *f; char filename[PATH_MAX]; BN_GENCB *cb; int result; fprintf(stderr, "Generating %d bits keys:\n", bits); cb = BN_GENCB_new(); if(!cb) { abort(); } BN_GENCB_set(cb, indicator, NULL); rsa_key = RSA_new(); if(BN_hex2bn(&e, "10001") == 0) { abort(); } if(!rsa_key || !e) { abort(); } result = RSA_generate_key_ex(rsa_key, bits, e, cb); BN_free(e); BN_GENCB_free(cb); if(!result) { fprintf(stderr, "Error during key generation!\n"); RSA_free(rsa_key); return false; } else { fprintf(stderr, "Done.\n"); } snprintf(filename, sizeof(filename), "%s/rsa_key.priv", confbase); f = ask_and_open(filename, "private RSA key"); if(!f) { RSA_free(rsa_key); return false; } #ifdef HAVE_FCHMOD /* Make it unreadable for others. */ fchmod(fileno(f), 0600); #endif fputc('\n', f); PEM_write_RSAPrivateKey(f, rsa_key, NULL, NULL, 0, NULL, NULL); fclose(f); char *name = get_name(); if(name) { snprintf(filename, sizeof(filename), "%s/hosts/%s", confbase, name); free(name); } else { snprintf(filename, sizeof(filename), "%s/rsa_key.pub", confbase); } f = ask_and_open(filename, "public RSA key"); if(!f) { RSA_free(rsa_key); return false; } fputc('\n', f); PEM_write_RSAPublicKey(f, rsa_key); fclose(f); RSA_free(rsa_key); return true; }
int tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, const char *cert_file, const char *cert_file_inline) { RSA *rsa = NULL; RSA *pub_rsa; RSA_METHOD *rsa_meth; X509 *cert = NULL; ASSERT (NULL != ctx); tls_ctx_load_cert_file_and_copy (ctx, cert_file, cert_file_inline, &cert); ASSERT (NULL != cert); /* allocate custom RSA method object */ ALLOC_OBJ_CLEAR (rsa_meth, RSA_METHOD); rsa_meth->name = "OpenVPN external private key RSA Method"; rsa_meth->rsa_pub_enc = rsa_pub_enc; rsa_meth->rsa_pub_dec = rsa_pub_dec; rsa_meth->rsa_priv_enc = rsa_priv_enc; rsa_meth->rsa_priv_dec = rsa_priv_dec; rsa_meth->init = NULL; rsa_meth->finish = rsa_finish; rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK; rsa_meth->app_data = NULL; /* allocate RSA object */ rsa = RSA_new(); if (rsa == NULL) { SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE); goto err; } /* get the public key */ ASSERT(cert->cert_info->key->pkey); /* NULL before SSL_CTX_use_certificate() is called */ pub_rsa = cert->cert_info->key->pkey->pkey.rsa; /* initialize RSA object */ rsa->n = BN_dup(pub_rsa->n); rsa->flags |= RSA_FLAG_EXT_PKEY; if (!RSA_set_method(rsa, rsa_meth)) goto err; /* bind our custom RSA object to ssl_ctx */ if (!SSL_CTX_use_RSAPrivateKey(ctx->ctx, rsa)) goto err; X509_free(cert); RSA_free(rsa); /* doesn't necessarily free, just decrements refcount */ return 1; err: if (cert) X509_free(cert); if (rsa) RSA_free(rsa); else { if (rsa_meth) free(rsa_meth); } msg (M_SSLERR, "Cannot enable SSL external private key capability"); return 0; }
int main(int argc, char **argv) { UNUSED(argc); UNUSED(argv); rsa = RSA_new(); e = BN_new(); pkey = EVP_PKEY_new(); if ((rsa == NULL) || (e == NULL) || (pkey == NULL) || !EVP_PKEY_set1_RSA(pkey, rsa)) { fprintf(stderr, "fatal error: basic OpenSSL failure\n"); exit(1); } /* e = 0x1000000000001 */ BN_set_bit(e, 0); BN_set_bit(e, 48); if (RSA_generate_key_ex(rsa, bits, e, NULL)) { BN_free(e); RSA_free(rsa); } else { fprintf(stderr, "fatal error: RSA_generate_key_ex() fails " "at file %s line %d\n", __FILE__, __LINE__); exit(1); } dns_result_register(); CHECK(isc_mem_create(0, 0, &mctx), "isc_mem_create()"); CHECK(isc_entropy_create(mctx, &ectx), "isc_entropy_create()"); CHECK(isc_entropy_usebestsource(ectx, &source, "random.data", ISC_ENTROPY_KEYBOARDNO), "isc_entropy_usebestsource(\"random.data\")"); CHECK(dst_lib_init2(mctx, ectx, NULL, 0), "dst_lib_init2()"); CHECK(isc_log_create(mctx, &log_, &logconfig), "isc_log_create()"); isc_log_setcontext(log_); dns_log_init(log_); dns_log_setcontext(log_); CHECK(isc_log_settag(logconfig, "bigkey"), "isc_log_settag()"); destination.file.stream = stderr; destination.file.name = NULL; destination.file.versions = ISC_LOG_ROLLNEVER; destination.file.maximum_size = 0; CHECK(isc_log_createchannel(logconfig, "stderr", ISC_LOG_TOFILEDESC, level, &destination, ISC_LOG_PRINTTAG | ISC_LOG_PRINTLEVEL), "isc_log_createchannel()"); CHECK(isc_log_usechannel(logconfig, "stderr", NULL, NULL), "isc_log_usechannel()"); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); isc_buffer_constinit(&buf, "example.", strlen("example.")); isc_buffer_add(&buf, strlen("example.")); CHECK(dns_name_fromtext(name, &buf, dns_rootname, 0, NULL), "dns_name_fromtext(\"example.\")"); CHECK(dst_key_buildinternal(name, DNS_KEYALG_RSASHA1, bits, DNS_KEYOWNER_ZONE, DNS_KEYPROTO_DNSSEC, dns_rdataclass_in, pkey, mctx, &key), "dst_key_buildinternal(...)"); CHECK(dst_key_tofile(key, DST_TYPE_PRIVATE | DST_TYPE_PUBLIC, NULL), "dst_key_tofile()"); isc_buffer_init(&buf, filename, sizeof(filename) - 1); isc_buffer_clear(&buf); CHECK(dst_key_buildfilename(key, 0, NULL, &buf), "dst_key_buildfilename()"); printf("%s\n", filename); dst_key_free(&key); isc_log_destroy(&log_); isc_log_setcontext(NULL); dns_log_setcontext(NULL); if (source != NULL) isc_entropy_destroysource(&source); isc_entropy_detach(&ectx); dst_lib_destroy(); dns_name_destroy(); isc_mem_destroy(&mctx); return (0); }
/** \ingroup HighLevel_KeyGenerate \brief Generates an RSA keypair \param numbits Modulus size \param e Public Exponent \param keydata Pointer to keydata struct to hold new key \return ops_true if key generated successfully; otherwise ops_false \note It is the caller's responsibility to call ops_keydata_free(keydata) */ ops_boolean_t ops_rsa_generate_keypair(const int numbits, const unsigned long e, ops_keydata_t* keydata) { ops_secret_key_t *skey=NULL; RSA *rsa=RSA_new(); BN_CTX *ctx=BN_CTX_new(); BIGNUM *ebn=BN_new(); ops_keydata_init(keydata,OPS_PTAG_CT_SECRET_KEY); skey=ops_get_writable_secret_key_from_data(keydata); // generate the key pair BN_set_word(ebn,e); RSA_generate_key_ex(rsa,numbits,ebn,NULL); // populate ops key from ssl key skey->public_key.version=4; skey->public_key.creation_time=time(NULL); skey->public_key.days_valid=0; skey->public_key.algorithm= OPS_PKA_RSA; skey->public_key.key.rsa.n=BN_dup(rsa->n); skey->public_key.key.rsa.e=BN_dup(rsa->e); skey->s2k_usage=OPS_S2KU_ENCRYPTED_AND_HASHED; skey->s2k_specifier=OPS_S2KS_SALTED; //skey->s2k_specifier=OPS_S2KS_SIMPLE; skey->algorithm=OPS_SA_CAST5; // \todo make param skey->hash_algorithm=OPS_HASH_SHA1; // \todo make param skey->octet_count=0; skey->checksum=0; skey->key.rsa.d=BN_dup(rsa->d); skey->key.rsa.p=BN_dup(rsa->p); skey->key.rsa.q=BN_dup(rsa->q); skey->key.rsa.u=BN_mod_inverse(NULL,rsa->p, rsa->q, ctx); assert(skey->key.rsa.u); BN_CTX_free(ctx); RSA_free(rsa); ops_keyid(keydata->key_id, &keydata->key.skey.public_key); ops_fingerprint(&keydata->fingerprint, &keydata->key.skey.public_key); // Generate checksum ops_create_info_t *cinfo=NULL; ops_memory_t *mem=NULL; ops_setup_memory_write(&cinfo, &mem, 128); ops_push_skey_checksum_writer(cinfo, skey); switch(skey->public_key.algorithm) { // case OPS_PKA_DSA: // return ops_write_mpi(key->key.dsa.x,info); case OPS_PKA_RSA: case OPS_PKA_RSA_ENCRYPT_ONLY: case OPS_PKA_RSA_SIGN_ONLY: if(!ops_write_mpi(skey->key.rsa.d,cinfo) || !ops_write_mpi(skey->key.rsa.p,cinfo) || !ops_write_mpi(skey->key.rsa.q,cinfo) || !ops_write_mpi(skey->key.rsa.u,cinfo)) return ops_false; break; // case OPS_PKA_ELGAMAL: // return ops_write_mpi(key->key.elgamal.x,info); default: assert(0); break; } // close rather than pop, since its the only one on the stack ops_writer_close(cinfo); ops_teardown_memory_write(cinfo, mem); // should now have checksum in skey struct // test if (debug) test_secret_key(skey); return ops_true; }
int genrsa_main(int argc, char **argv) { BN_GENCB cb; int ret = 1; int i, num = DEFBITS; long l; const EVP_CIPHER *enc = NULL; unsigned long f4 = RSA_F4; char *outfile = NULL; char *passargout = NULL, *passout = NULL; BIO *out = NULL; BIGNUM *bn = BN_new(); RSA *rsa = NULL; if (single_execution) { if (pledge("stdio cpath wpath rpath tty", NULL) == -1) { perror("pledge"); exit(1); } } if (!bn) goto err; BN_GENCB_set(&cb, genrsa_cb, bio_err); if ((out = BIO_new(BIO_s_file())) == NULL) { BIO_printf(bio_err, "unable to create BIO for output\n"); goto err; } argv++; argc--; for (;;) { if (argc <= 0) break; if (strcmp(*argv, "-out") == 0) { if (--argc < 1) goto bad; outfile = *(++argv); } else if (strcmp(*argv, "-3") == 0) f4 = 3; else if (strcmp(*argv, "-F4") == 0 || strcmp(*argv, "-f4") == 0) f4 = RSA_F4; #ifndef OPENSSL_NO_DES else if (strcmp(*argv, "-des") == 0) enc = EVP_des_cbc(); else if (strcmp(*argv, "-des3") == 0) enc = EVP_des_ede3_cbc(); #endif #ifndef OPENSSL_NO_IDEA else if (strcmp(*argv, "-idea") == 0) enc = EVP_idea_cbc(); #endif #ifndef OPENSSL_NO_AES else if (strcmp(*argv, "-aes128") == 0) enc = EVP_aes_128_cbc(); else if (strcmp(*argv, "-aes192") == 0) enc = EVP_aes_192_cbc(); else if (strcmp(*argv, "-aes256") == 0) enc = EVP_aes_256_cbc(); #endif #ifndef OPENSSL_NO_CAMELLIA else if (strcmp(*argv, "-camellia128") == 0) enc = EVP_camellia_128_cbc(); else if (strcmp(*argv, "-camellia192") == 0) enc = EVP_camellia_192_cbc(); else if (strcmp(*argv, "-camellia256") == 0) enc = EVP_camellia_256_cbc(); #endif else if (strcmp(*argv, "-passout") == 0) { if (--argc < 1) goto bad; passargout = *(++argv); } else break; argv++; argc--; } if ((argc >= 1) && ((sscanf(*argv, "%d", &num) == 0) || (num < 0))) { bad: BIO_printf(bio_err, "usage: genrsa [args] [numbits]\n"); BIO_printf(bio_err, " -des encrypt the generated key with DES in cbc mode\n"); BIO_printf(bio_err, " -des3 encrypt the generated key with DES in ede cbc mode (168 bit key)\n"); #ifndef OPENSSL_NO_IDEA BIO_printf(bio_err, " -idea encrypt the generated key with IDEA in cbc mode\n"); #endif #ifndef OPENSSL_NO_AES BIO_printf(bio_err, " -aes128, -aes192, -aes256\n"); BIO_printf(bio_err, " encrypt PEM output with cbc aes\n"); #endif #ifndef OPENSSL_NO_CAMELLIA BIO_printf(bio_err, " -camellia128, -camellia192, -camellia256\n"); BIO_printf(bio_err, " encrypt PEM output with cbc camellia\n"); #endif BIO_printf(bio_err, " -out file output the key to 'file\n"); BIO_printf(bio_err, " -passout arg output file pass phrase source\n"); BIO_printf(bio_err, " -f4 use F4 (0x10001) for the E value\n"); BIO_printf(bio_err, " -3 use 3 for the E value\n"); goto err; } if (!app_passwd(bio_err, NULL, passargout, NULL, &passout)) { BIO_printf(bio_err, "Error getting password\n"); goto err; } if (outfile == NULL) { BIO_set_fp(out, stdout, BIO_NOCLOSE); } else { if (BIO_write_filename(out, outfile) <= 0) { perror(outfile); goto err; } } BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus\n", num); rsa = RSA_new(); if (!rsa) goto err; if (!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, &cb)) goto err; /* * We need to do the following for when the base number size is < * long, esp windows 3.1 :-(. */ l = 0L; for (i = 0; i < rsa->e->top; i++) { #ifndef _LP64 l <<= BN_BITS4; l <<= BN_BITS4; #endif l += rsa->e->d[i]; } BIO_printf(bio_err, "e is %ld (0x%lX)\n", l, l); { PW_CB_DATA cb_data; cb_data.password = passout; cb_data.prompt_info = outfile; if (!PEM_write_bio_RSAPrivateKey(out, rsa, enc, NULL, 0, password_callback, &cb_data)) goto err; } ret = 0; err: BN_free(bn); RSA_free(rsa); BIO_free_all(out); free(passout); if (ret != 0) ERR_print_errors(bio_err); return (ret); }
/* TODO: Maybe, basic container validation should be put in separate functions outside of engine-specific code */ soter_status_t soter_rsa_pub_key_to_engine_specific(const soter_container_hdr_t *key, size_t key_length, soter_engine_specific_rsa_key_t **engine_key) { int rsa_mod_size; RSA *rsa; EVP_PKEY *pkey = (EVP_PKEY *)(*engine_key); const uint32_t *pub_exp; if (key_length != ntohl(key->size)) { return SOTER_INVALID_PARAMETER; } /* Validate tag */ if (memcmp(key->tag, RSA_PUB_KEY_PREF, strlen(RSA_PUB_KEY_PREF))) { return SOTER_INVALID_PARAMETER; } if (SOTER_SUCCESS != soter_verify_container_checksum(key)) { return SOTER_DATA_CORRUPT; } switch (key->tag[3]) { case '1': rsa_mod_size = 128; break; case '2': rsa_mod_size = 256; break; case '4': rsa_mod_size = 512; break; case '8': rsa_mod_size = 1024; break; default: return SOTER_INVALID_PARAMETER; } if (key_length < rsa_pub_key_size(rsa_mod_size)) { return SOTER_INVALID_PARAMETER; } pub_exp = (const uint32_t *)((unsigned char *)(key + 1) + rsa_mod_size); switch (ntohl(*pub_exp)) { case RSA_3: case RSA_F4: break; default: return SOTER_INVALID_PARAMETER; } rsa = RSA_new(); if (!rsa) { return SOTER_NO_MEMORY; } rsa->e = BN_new(); if (!(rsa->e)) { RSA_free(rsa); return SOTER_NO_MEMORY; } if (!BN_set_word(rsa->e, ntohl(*pub_exp))) { RSA_free(rsa); return SOTER_FAIL; } rsa->n = BN_new(); if (!(rsa->n)) { RSA_free(rsa); return SOTER_NO_MEMORY; } if (!BN_bin2bn((const unsigned char *)(key + 1), rsa_mod_size, rsa->n)) { RSA_free(rsa); return SOTER_FAIL; } if (!EVP_PKEY_assign_RSA(pkey, rsa)) { RSA_free(rsa); return SOTER_FAIL; } /* EVP_PKEY_assign_RSA does not increment the reference count, so no need to free RSA object */ return SOTER_SUCCESS; }
static EVP_PKEY *ssh2_line_to_key(char *line) { EVP_PKEY *key; RSA *rsa; unsigned char decoded[OPENSSH_LINE_MAX]; int len; char *b, *c; int i; /* find the mime-blob */ b = line; if (!b) return NULL; /* find the first whitespace */ while (*b && *b != ' ') b++; /* skip that whitespace */ b++; /* find the end of the blob / comment */ for (c = b; *c && *c != ' ' && 'c' != '\t' && *c != '\r' && *c != '\n'; c++) ; *c = 0; /* decode binary data */ if (sc_base64_decode(b, decoded, OPENSSH_LINE_MAX) < 0) return NULL; i = 0; /* get integer from blob */ len = (decoded[i] << 24) + (decoded[i + 1] << 16) + (decoded[i + 2] << 8) + (decoded[i + 3]); i += 4; /* now: key_from_blob */ if (strncmp((char *)&decoded[i], "ssh-rsa", 7) != 0) return NULL; i += len; key = EVP_PKEY_new(); rsa = RSA_new(); /* get integer from blob */ len = (decoded[i] << 24) + (decoded[i + 1] << 16) + (decoded[i + 2] << 8) + (decoded[i + 3]); i += 4; /* get bignum */ rsa->e = BN_bin2bn(decoded + i, len, NULL); i += len; /* get integer from blob */ len = (decoded[i] << 24) + (decoded[i + 1] << 16) + (decoded[i + 2] << 8) + (decoded[i + 3]); i += 4; /* get bignum */ rsa->n = BN_bin2bn(decoded + i, len, NULL); EVP_PKEY_assign_RSA(key, rsa); return key; }
static EVP_PKEY *tpm_engine_load_key(ENGINE *e, const char *key_id, UI_METHOD *ui, void *cb_data) { ASN1_OCTET_STRING *blobstr; TSS_HKEY hKey; TSS_RESULT result; UINT32 authusage; RSA *rsa; EVP_PKEY *pkey; BIO *bf; DBG("%s", __FUNCTION__); if (!key_id) { TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, ERR_R_PASSED_NULL_PARAMETER); return NULL; } if (!tpm_load_srk(ui, cb_data)) { TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_SRK_LOAD_FAILED); return NULL; } if ((bf = BIO_new_file(key_id, "r")) == NULL) { TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_FILE_NOT_FOUND); return NULL; } blobstr = PEM_ASN1_read_bio((void *)d2i_ASN1_OCTET_STRING, "TSS KEY BLOB", bf, NULL, NULL, NULL); if (!blobstr) { TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_FILE_READ_FAILED); BIO_free(bf); return NULL; } BIO_free(bf); DBG("Loading blob of size: %d", blobstr->length); if ((result = Tspi_Context_LoadKeyByBlob(hContext, hSRK, blobstr->length, blobstr->data, &hKey))) { TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_REQUEST_FAILED); return NULL; } ASN1_OCTET_STRING_free(blobstr); if ((result = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO, TSS_TSPATTRIB_KEYINFO_AUTHUSAGE, &authusage))) { Tspi_Context_CloseObject(hContext, hKey); TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_REQUEST_FAILED); return NULL; } if (authusage) { TSS_HPOLICY hPolicy; BYTE *auth; if ((auth = calloc(1, 128)) == NULL) { Tspi_Context_CloseObject(hContext, hKey); TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, ERR_R_MALLOC_FAILURE); return NULL; } if (!tpm_engine_get_auth(ui, (char *)auth, 128, "TPM Key Password: ", cb_data)) { Tspi_Context_CloseObject(hContext, hKey); free(auth); TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_REQUEST_FAILED); return NULL; } if ((result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hPolicy))) { Tspi_Context_CloseObject(hContext, hKey); free(auth); TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_REQUEST_FAILED); return 0; } if ((result = Tspi_Policy_AssignToObject(hPolicy, hKey))) { Tspi_Context_CloseObject(hContext, hKey); Tspi_Context_CloseObject(hContext, hPolicy); free(auth); TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_REQUEST_FAILED); return 0; } if ((result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_PLAIN, strlen((char *)auth), auth))) { Tspi_Context_CloseObject(hContext, hKey); Tspi_Context_CloseObject(hContext, hPolicy); free(auth); TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_REQUEST_FAILED); return 0; } free(auth); } /* create the new objects to return */ if ((pkey = EVP_PKEY_new()) == NULL) { Tspi_Context_CloseObject(hContext, hKey); TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, ERR_R_MALLOC_FAILURE); return NULL; } pkey->type = EVP_PKEY_RSA; if ((rsa = RSA_new()) == NULL) { EVP_PKEY_free(pkey); Tspi_Context_CloseObject(hContext, hKey); TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, ERR_R_MALLOC_FAILURE); return NULL; } rsa->meth = &tpm_rsa; /* call our local init function here */ rsa->meth->init(rsa); pkey->pkey.rsa = rsa; if (!fill_out_rsa_object(rsa, hKey)) { EVP_PKEY_free(pkey); RSA_free(rsa); Tspi_Context_CloseObject(hContext, hKey); TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_REQUEST_FAILED); return NULL; } EVP_PKEY_assign_RSA(pkey, rsa); return pkey; }
static EVP_PKEY *ssh1_line_to_key(char *line) { EVP_PKEY *key; RSA *rsa; char *b, *e, *m, *c; key = EVP_PKEY_new(); if (!key) return NULL; rsa = RSA_new(); if (!rsa) goto err; /* first digitstring: the bits */ b = line; /* second digitstring: the exponent */ /* skip all digits */ for (e = b; *e >= '0' && *e <= '0'; e++) ; /* must be a whitespace */ if (*e != ' ' && *e != '\t') return NULL; /* cut the string in two part */ *e = 0; e++; /* skip more whitespace */ while (*e == ' ' || *e == '\t') e++; /* third digitstring: the modulus */ /* skip all digits */ for (m = e; *m >= '0' && *m <= '0'; m++) ; /* must be a whitespace */ if (*m != ' ' && *m != '\t') return NULL; /* cut the string in two part */ *m = 0; m++; /* skip more whitespace */ while (*m == ' ' || *m == '\t') m++; /* look for a comment after the modulus */ for (c = m; *c >= '0' && *c <= '0'; c++) ; /* could be a whitespace or end of line */ if (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\r' && *c != 0) return NULL; if (*c == ' ' || *c == '\t') { *c = 0; c++; /* skip more whitespace */ while (*c == ' ' || *c == '\t') c++; if (*c && *c != '\r' && *c != '\n') { /* we have a comment */ } else { c = NULL; } } else { *c = 0; c = NULL; } /* ok, now we have b e m pointing to pure digit * null terminated strings and maybe c pointing to a comment */ BN_dec2bn(&rsa->e, e); BN_dec2bn(&rsa->n, m); EVP_PKEY_assign_RSA(key, rsa); return key; err: free(key); return NULL; }
static int collect_private_key(hx509_context context, struct p11_module *p, struct p11_slot *slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object, void *ptr, CK_ATTRIBUTE *query, int num_query) { struct hx509_collector *collector = ptr; hx509_private_key key; heim_octet_string localKeyId; int ret; RSA *rsa; struct p11_rsa *p11rsa; localKeyId.data = query[0].pValue; localKeyId.length = query[0].ulValueLen; ret = hx509_private_key_init(&key, NULL, NULL); if (ret) return ret; rsa = RSA_new(); if (rsa == NULL) _hx509_abort("out of memory"); /* * The exponent and modulus should always be present according to * the pkcs11 specification, but some smartcards leaves it out, * let ignore any failure to fetch it. */ rsa->n = getattr_bn(p, slot, session, object, CKA_MODULUS); rsa->e = getattr_bn(p, slot, session, object, CKA_PUBLIC_EXPONENT); p11rsa = calloc(1, sizeof(*p11rsa)); if (p11rsa == NULL) _hx509_abort("out of memory"); p11rsa->p = p; p11rsa->slot = slot; p11rsa->private_key = object; if (p->ref == 0) _hx509_abort("pkcs11 ref == 0 on alloc"); p->ref++; if (p->ref == UINT_MAX) _hx509_abort("pkcs11 ref == UINT_MAX on alloc"); RSA_set_method(rsa, &p11_rsa_pkcs1_method); ret = RSA_set_app_data(rsa, p11rsa); if (ret != 1) _hx509_abort("RSA_set_app_data"); hx509_private_key_assign_rsa(key, rsa); ret = _hx509_collector_private_key_add(context, collector, hx509_signature_rsa(), key, NULL, &localKeyId); if (ret) { hx509_private_key_free(&key); return ret; } return 0; }
int main(int argc, char** argv) { R_RSA_PUBLIC_KEY public_key; R_RSA_PRIVATE_KEY private_key; int i, n, retval; bool is_valid; DATA_BLOCK signature, in, out; unsigned char signature_buf[256], buf[256], buf2[256]; FILE *f, *fpriv, *fpub; char cbuf[256]; RSA rsa_key; RSA *rsa_key_; BIO *bio_out=NULL; BIO *bio_err=NULL; char *certpath; bool b2o=false; // boinc key to openssl key ? bool kpriv=false; // private key ? if (argc == 1) { usage(); exit(1); } if (!strcmp(argv[1], "-genkey")) { if (argc < 5) { usage(); exit(1); } printf("creating keys in %s and %s\n", argv[3], argv[4]); n = atoi(argv[2]); srand(random_int()); RSA* rp = RSA_generate_key(n, 65537, 0, 0); openssl_to_keys(rp, n, private_key, public_key); fpriv = fopen(argv[3], "w"); if (!fpriv) die("fopen"); fpub = fopen(argv[4], "w"); if (!fpub) die("fopen"); print_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key)); print_key_hex(fpub, (KEY*)&public_key, sizeof(public_key)); } else if (!strcmp(argv[1], "-sign")) { if (argc < 4) { usage(); exit(1); } fpriv = fopen(argv[3], "r"); if (!fpriv) die("fopen"); retval = scan_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key)); if (retval) die("scan_key_hex\n"); signature.data = signature_buf; signature.len = 256; retval = sign_file(argv[2], private_key, signature); print_hex_data(stdout, signature); } else if (!strcmp(argv[1], "-sign_string")) { if (argc < 4) { usage(); exit(1); } fpriv = fopen(argv[3], "r"); if (!fpriv) die("fopen"); retval = scan_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key)); if (retval) die("scan_key_hex\n"); generate_signature(argv[2], cbuf, private_key); puts(cbuf); } else if (!strcmp(argv[1], "-verify")) { if (argc < 5) { usage(); exit(1); } fpub = fopen(argv[4], "r"); if (!fpub) die("fopen"); retval = scan_key_hex(fpub, (KEY*)&public_key, sizeof(public_key)); if (retval) die("read_public_key"); f = fopen(argv[3], "r"); signature.data = signature_buf; signature.len = 256; retval = scan_hex_data(f, signature); if (retval) die("scan_hex_data"); retval = verify_file(argv[2], public_key, signature, is_valid); if (retval) die("verify_file"); if (is_valid) { printf("file is valid\n"); } else { printf("file is invalid\n"); return 1; } } else if (!strcmp(argv[1], "-test_crypt")) { if (argc < 4) { usage(); exit(1); } fpriv = fopen(argv[2], "r"); if (!fpriv) die("fopen"); retval = scan_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key)); if (retval) die("scan_key_hex\n"); fpub = fopen(argv[3], "r"); if (!fpub) die("fopen"); retval = scan_key_hex(fpub, (KEY*)&public_key, sizeof(public_key)); if (retval) die("read_public_key"); strcpy((char*)buf2, "encryption test successful"); in.data = buf2; in.len = strlen((char*)in.data); out.data = buf; encrypt_private(private_key, in, out); in = out; out.data = buf2; decrypt_public(public_key, in, out); printf("out: %s\n", out.data); } else if (!strcmp(argv[1], "-cert_verify")) { if (argc < 6) die("usage: crypt_prog -cert_verify file signature_file certificate_dir ca_dir \n"); f = fopen(argv[3], "r"); signature.data = signature_buf; signature.len = 256; retval = scan_hex_data(f, signature); if (retval) die("cannot scan_hex_data"); certpath = check_validity(argv[4], argv[2], signature.data, argv[5]); if (certpath == NULL) { die("signature cannot be verfied.\n\n"); } else { printf("siganture verified using certificate '%s'.\n\n", certpath); free(certpath); } // this converts, but an executable signed with sign_executable, // and signature converted to OpenSSL format cannot be verified with // OpenSSL } else if (!strcmp(argv[1], "-convsig")) { if (argc < 5) { usage(); exit(1); } if (strcmp(argv[2], "b2o") == 0) { b2o = true; } else if (strcmp(argv[2], "o2b") == 0) { b2o = false; } else { die("either 'o2b' or 'b2o' must be defined for -convsig\n"); } if (b2o) { f = fopen(argv[3], "r"); signature.data = signature_buf; signature.len = 256; retval = scan_hex_data(f, signature); fclose(f); f = fopen(argv[4], "w+"); print_raw_data(f, signature); fclose(f); } else { f = fopen(argv[3], "r"); signature.data = signature_buf; signature.len = 256; retval = scan_raw_data(f, signature); fclose(f); f = fopen(argv[4], "w+"); print_hex_data(f, signature); fclose(f); } } else if (!strcmp(argv[1], "-convkey")) { if (argc < 6) { usage(); exit(1); } if (strcmp(argv[2], "b2o") == 0) { b2o = true; } else if (strcmp(argv[2], "o2b") == 0) { b2o = false; } else { die("either 'o2b' or 'b2o' must be defined for -convkey\n"); } if (strcmp(argv[3], "pub") == 0) { kpriv = false; } else if (strcmp(argv[3], "priv") == 0) { kpriv = true; } else { die("either 'pub' or 'priv' must be defined for -convkey\n"); } OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); ENGINE_load_builtin_engines(); if (bio_err == NULL) { bio_err = BIO_new_fp(stdout, BIO_NOCLOSE); } //enc=EVP_get_cipherbyname("des"); //if (enc == NULL) // die("could not get cypher.\n"); // no encription yet. bio_out=BIO_new(BIO_s_file()); if (BIO_write_filename(bio_out,argv[5]) <= 0) { perror(argv[5]); die("could not create output file.\n"); } if (b2o) { rsa_key_ = RSA_new(); if (kpriv) { fpriv = fopen(argv[4], "r"); if (!fpriv) { die("fopen"); } scan_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key)); fclose(fpriv); private_to_openssl(private_key, &rsa_key); //i = PEM_write_bio_RSAPrivateKey(bio_out, &rsa_key, // enc, NULL, 0, pass_cb, NULL); // no encryption yet. //i = PEM_write_bio_RSAPrivateKey(bio_out, &rsa_key, // NULL, NULL, 0, pass_cb, NULL); fpriv = fopen(argv[5], "w+"); PEM_write_RSAPrivateKey(fpriv, &rsa_key, NULL, NULL, 0, 0, NULL); fclose(fpriv); //if (i == 0) { // ERR_print_errors(bio_err); // die("could not write key file.\n"); //} } else { fpub = fopen(argv[4], "r"); if (!fpub) { die("fopen"); } scan_key_hex(fpub, (KEY*)&public_key, sizeof(public_key)); fclose(fpub); fpub = fopen(argv[5], "w+"); if (!fpub) { die("fopen"); } public_to_openssl(public_key, rsa_key_); i = PEM_write_RSA_PUBKEY(fpub, rsa_key_); if (i == 0) { ERR_print_errors(bio_err); die("could not write key file.\n"); } fclose(fpub); } } else { // o2b rsa_key_ = (RSA *)calloc(1, sizeof(RSA)); memset(rsa_key_, 0, sizeof(RSA)); if (rsa_key_ == NULL) { die("could not allocate memory for RSA structure.\n"); } if (kpriv) { fpriv = fopen (argv[4], "r"); rsa_key_ = PEM_read_RSAPrivateKey(fpriv, NULL, NULL, NULL); fclose(fpriv); if (rsa_key_ == NULL) { ERR_print_errors(bio_err); die("could not load private key.\n"); } openssl_to_private(rsa_key_, &private_key); fpriv = fopen(argv[5], "w"); if (!fpriv) { die("fopen"); } print_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key)); } else { fpub = fopen (argv[4], "r"); rsa_key_ = PEM_read_RSA_PUBKEY(fpub, NULL, NULL, NULL); fclose(fpub); if (rsa_key_ == NULL) { ERR_print_errors(bio_err); die("could not load public key.\n"); } openssl_to_keys(rsa_key_, 1024, private_key, public_key); //openssl_to_public(rsa_key_, &public_key); public_to_openssl(public_key, rsa_key_); // fpub = fopen(argv[5], "w"); if (!fpub) { die("fopen"); } print_key_hex(fpub, (KEY*)&public_key, sizeof(public_key)); } } } else { usage(); exit(1); } return 0; }
/* Parse DER encoded asn.1 RSA public key out of a certificate stream. We reach here with 'pp' pointing to the byte after the algorithm identifier. */ int32_t psRsaParseAsnPubKey(psPool_t *pool, const unsigned char **pp, psSize_t len, psRsaKey_t *key, unsigned char sha1KeyHash[SHA1_HASH_SIZE]) { # ifdef USE_SHA1 psDigestContext_t dc; # endif const unsigned char *p = *pp; RSA *rsa; psSize_t keylen; # ifndef USE_D2I psSize_t seqlen; # endif if (len < 1 || (*(p++) != ASN_BIT_STRING) || getAsnLength(&p, len - 1, &keylen)) { goto L_FAIL; } /* ignored bits field should be zero */ if (*p++ != 0) { goto L_FAIL; } keylen--; # ifdef USE_SHA1 /* A public key hash is used in PKI tools (OCSP, Trusted CA indication). Standard RSA form - SHA-1 hash of the value of the BIT STRING subjectPublicKey [excluding the tag, length, and number of unused bits] */ psSha1Init(&dc.sha1); psSha1Update(&dc.sha1, p, keylen); psSha1Final(&dc.sha1, sha1KeyHash); # endif # ifdef USE_D2I /* OpenSSL expects to parse after the ignored bits field */ if ((rsa = d2i_RSAPublicKey(NULL, &p, keylen)) == NULL) { goto L_FAIL; } # else /* We can manually create the structures as OpenSSL would */ rsa = RSA_new(); if (getAsnSequence(&p, keylen, &seqlen) < 0 || getBig(&p, seqlen, &rsa->n) < 0 || getBig(&p, seqlen, &rsa->e) < 0) { RSA_free(rsa); goto L_FAIL; } # endif /* RSA_print_fp(stdout, rsa, 0); */ *pp = p; *key = rsa; return PS_SUCCESS; L_FAIL: psTraceIntCrypto("psRsaParseAsnPubKey error on byte %d\n", p - *pp); return PS_PARSE_FAIL; }
int main() { unsigned char ibuf[128], obuf[128]; int i, ifd, ofd, ilen, olen, sz_enc, sz_dec; ilen = olen = 128; FILE *prk; prk = fopen("/home/sgupta/tmp/pr.key", "r"); if (prk == NULL) { printf("life sucks!\n"); exit(1); } else { printf("life looks good!\n"); } RSA *rsa, *rsa2; rsa = RSA_new(); //rsa2 = RSA_new(); if ((rsa2 = PEM_read_RSAPrivateKey(prk, &rsa, NULL, NULL)) != NULL) { printf("key size: %d\n", RSA_size(rsa)); } if (RSA_check_key(rsa)) { printf("life is sweet!\n"); } if ((ifd = open("/home/sgupta/tmp/encc", O_RDONLY)) > 0) { printf("opened encrypted file!\n"); memset(ibuf, 0, ilen); if ((ilen = read(ifd, ibuf, ilen)) > 0) { printf("%d bytes read from input file\n", ilen); memset(obuf, 0, olen); if ((sz_dec = RSA_private_decrypt(ilen, ibuf, obuf, rsa, RSA_PKCS1_PADDING)) > -1) { printf("size of decrypted text: %d\n", sz_dec); printf("decrypted text -> "); for (i = 0; i < sz_dec; i++) { printf("%x", obuf[i]); if (i < sz_dec - 1) printf(":"); } printf("\n"); } } } /* if ((ifd = open("/home/sgupta/tmp/cc", O_RDONLY)) > 0) { printf("opened text file!\n"); memset(ibuf, 0, ilen); if ((ilen = read(ifd, ibuf, ilen)) > 0) { printf("%d bytes read from input file\n", ilen); memset(obuf, 0, olen); if ((sz_enc = RSA_public_encrypt(ilen, ibuf, obuf, rsa, RSA_NO_PADDING)) > -1) { printf("size of encrypted text: %d\n", sz_enc); printf("encrypted text -> "); for (i = 0; i < sz_enc; i++) { printf("%02x", obuf[i]); if (i < sz_enc - 1) printf(":"); } printf("\n"); } } }*/ }
static int test_invalid_keypair(void) { int ret = 0; RSA *key = NULL; BN_CTX *ctx = NULL; BIGNUM *p = NULL, *q = NULL, *n = NULL, *e = NULL, *d = NULL; ret = TEST_ptr(key = RSA_new()) && TEST_ptr(ctx = BN_CTX_new()) /* NULL parameters */ && TEST_false(rsa_sp800_56b_check_keypair(key, NULL, -1, 2048)) /* load key */ && TEST_ptr(p = bn_load_new(cav_p, sizeof(cav_p))) && TEST_ptr(q = bn_load_new(cav_q, sizeof(cav_q))) && TEST_true(RSA_set0_factors(key, p, q)); if (!ret) { BN_free(p); BN_free(q); goto end; } ret = TEST_ptr(e = bn_load_new(cav_e, sizeof(cav_e))) && TEST_ptr(n = bn_load_new(cav_n, sizeof(cav_n))) && TEST_ptr(d = bn_load_new(cav_d, sizeof(cav_d))) && TEST_true(RSA_set0_key(key, n, e, d)); if (!ret) { BN_free(e); BN_free(n); BN_free(d); goto end; } /* bad strength/key size */ ret = TEST_false(rsa_sp800_56b_check_keypair(key, NULL, 100, 2048)) && TEST_false(rsa_sp800_56b_check_keypair(key, NULL, 112, 1024)) && TEST_false(rsa_sp800_56b_check_keypair(key, NULL, 128, 2048)) && TEST_false(rsa_sp800_56b_check_keypair(key, NULL, 140, 3072)) /* mismatching exponent */ && TEST_false(rsa_sp800_56b_check_keypair(key, BN_value_one(), -1, 2048)) /* bad exponent */ && TEST_true(BN_add_word(e, 1)) && TEST_false(rsa_sp800_56b_check_keypair(key, NULL, -1, 2048)) && TEST_true(BN_sub_word(e, 1)) /* mismatch between bits and modulus */ && TEST_false(rsa_sp800_56b_check_keypair(key, NULL, -1, 3072)) && TEST_true(rsa_sp800_56b_check_keypair(key, e, 112, 2048)) /* check n == pq failure */ && TEST_true(BN_add_word(n, 1)) && TEST_false(rsa_sp800_56b_check_keypair(key, NULL, -1, 2048)) && TEST_true(BN_sub_word(n, 1)) /* check p */ && TEST_true(BN_sub_word(p, 2)) && TEST_true(BN_mul(n, p, q, ctx)) && TEST_false(rsa_sp800_56b_check_keypair(key, NULL, -1, 2048)) && TEST_true(BN_add_word(p, 2)) && TEST_true(BN_mul(n, p, q, ctx)) /* check q */ && TEST_true(BN_sub_word(q, 2)) && TEST_true(BN_mul(n, p, q, ctx)) && TEST_false(rsa_sp800_56b_check_keypair(key, NULL, -1, 2048)) && TEST_true(BN_add_word(q, 2)) && TEST_true(BN_mul(n, p, q, ctx)); end: RSA_free(key); BN_CTX_free(ctx); return ret; }
int main(int argc, char *argv[]) { int err = 0; int v; RSA *key; unsigned char ptext[256]; unsigned char ctext[256]; static unsigned char ptext_ex[] = "\x54\x85\x9b\x34\x2c\x49\xea\x2a"; unsigned char ctext_ex[256]; int plen; int clen = 0; int num; int n; CRYPTO_set_mem_debug(1); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); RAND_seed(rnd_seed, sizeof(rnd_seed)); /* or OAEP may fail */ plen = sizeof(ptext_ex) - 1; for (v = 0; v < 3; v++) { key = RSA_new(); switch (v) { case 0: clen = key1(key, ctext_ex); break; case 1: clen = key2(key, ctext_ex); break; case 2: clen = key3(key, ctext_ex); break; } num = RSA_public_encrypt(plen, ptext_ex, ctext, key, RSA_PKCS1_PADDING); if (num != clen) { printf("PKCS#1 v1.5 encryption failed!\n"); err = 1; goto oaep; } num = RSA_private_decrypt(num, ctext, ptext, key, RSA_PKCS1_PADDING); if (num != plen || memcmp(ptext, ptext_ex, num) != 0) { printf("PKCS#1 v1.5 decryption failed!\n"); err = 1; } else printf("PKCS #1 v1.5 encryption/decryption ok\n"); oaep: ERR_clear_error(); num = RSA_public_encrypt(plen, ptext_ex, ctext, key, RSA_PKCS1_OAEP_PADDING); if (num == -1 && pad_unknown()) { printf("No OAEP support\n"); goto next; } if (num != clen) { printf("OAEP encryption failed!\n"); err = 1; goto next; } num = RSA_private_decrypt(num, ctext, ptext, key, RSA_PKCS1_OAEP_PADDING); if (num != plen || memcmp(ptext, ptext_ex, num) != 0) { printf("OAEP decryption (encrypted data) failed!\n"); err = 1; } else if (memcmp(ctext, ctext_ex, num) == 0) printf("OAEP test vector %d passed!\n", v); /* * Different ciphertexts (rsa_oaep.c without -DPKCS_TESTVECT). Try * decrypting ctext_ex */ num = RSA_private_decrypt(clen, ctext_ex, ptext, key, RSA_PKCS1_OAEP_PADDING); if (num != plen || memcmp(ptext, ptext_ex, num) != 0) { printf("OAEP decryption (test vector data) failed!\n"); err = 1; } else printf("OAEP encryption/decryption ok\n"); /* Try decrypting corrupted ciphertexts. */ for (n = 0; n < clen; ++n) { ctext[n] ^= 1; num = RSA_private_decrypt(clen, ctext, ptext, key, RSA_PKCS1_OAEP_PADDING); if (num > 0) { printf("Corrupt data decrypted!\n"); err = 1; break; } ctext[n] ^= 1; } /* Test truncated ciphertexts, as well as negative length. */ for (n = -1; n < clen; ++n) { num = RSA_private_decrypt(n, ctext, ptext, key, RSA_PKCS1_OAEP_PADDING); if (num > 0) { printf("Truncated data decrypted!\n"); err = 1; break; } } next: RSA_free(key); } #ifndef OPENSSL_NO_CRYPTO_MDEBUG if (CRYPTO_mem_leaks_fp(stderr) <= 0) err = 1; #endif return err; }
int main(int argc, char *argv[]) { int err=0; int v; RSA *key; unsigned char ptext[256]; unsigned char ctext[256]; static unsigned char ptext_ex[] = "\x54\x85\x9b\x34\x2c\x49\xea\x2a"; unsigned char ctext_ex[256]; int plen; int clen = 0; int num; CRYPTO_malloc_debug_init(); CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); RAND_seed(rnd_seed, sizeof rnd_seed); /* or OAEP may fail */ plen = sizeof(ptext_ex) - 1; for (v = 0; v < 3; v++) { key = RSA_new(); switch (v) { case 0: clen = key1(key, ctext_ex); break; case 1: clen = key2(key, ctext_ex); break; case 2: clen = key3(key, ctext_ex); break; } num = RSA_public_encrypt(plen, ptext_ex, ctext, key, RSA_PKCS1_PADDING); if (num != clen) { printf("PKCS#1 v1.5 encryption failed!\n"); err=1; goto oaep; } num = RSA_private_decrypt(num, ctext, ptext, key, RSA_PKCS1_PADDING); if (num != plen || memcmp(ptext, ptext_ex, num) != 0) { printf("PKCS#1 v1.5 decryption failed!\n"); err=1; } else printf("PKCS #1 v1.5 encryption/decryption ok\n"); oaep: ERR_clear_error(); num = RSA_public_encrypt(plen, ptext_ex, ctext, key, RSA_PKCS1_OAEP_PADDING); if (num == -1 && pad_unknown()) { printf("No OAEP support\n"); goto next; } if (num != clen) { printf("OAEP encryption failed!\n"); err=1; goto next; } num = RSA_private_decrypt(num, ctext, ptext, key, RSA_PKCS1_OAEP_PADDING); if (num != plen || memcmp(ptext, ptext_ex, num) != 0) { printf("OAEP decryption (encrypted data) failed!\n"); err=1; } else if (memcmp(ctext, ctext_ex, num) == 0) { printf("OAEP test vector %d passed!\n", v); goto next; } /* Different ciphertexts (rsa_oaep.c without -DPKCS_TESTVECT). Try decrypting ctext_ex */ num = RSA_private_decrypt(clen, ctext_ex, ptext, key, RSA_PKCS1_OAEP_PADDING); if (num != plen || memcmp(ptext, ptext_ex, num) != 0) { printf("OAEP decryption (test vector data) failed!\n"); err=1; } else printf("OAEP encryption/decryption ok\n"); next: RSA_free(key); } CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); CRYPTO_mem_leaks_fp(stderr); return err; }
RSAKeyImpl::RSAKeyImpl( const std::string& publicKeyFile, const std::string& privateKeyFile, const std::string& privateKeyPassphrase): _pRSA(0) { poco_assert_dbg(_pRSA == 0); _pRSA = RSA_new(); if (!publicKeyFile.empty()) { BIO* bio = BIO_new(BIO_s_file()); if (!bio) throw Poco::IOException("Cannot create BIO for reading public key", publicKeyFile); int rc = BIO_read_filename(bio, publicKeyFile.c_str()); if (rc) { RSA* pubKey = PEM_read_bio_RSAPublicKey(bio, &_pRSA, 0, 0); if (!pubKey) { int rc = BIO_seek(bio, 0); if (rc != 0) throw Poco::FileException("Failed to load public key", publicKeyFile); pubKey = PEM_read_bio_RSA_PUBKEY(bio, &_pRSA, 0, 0); } BIO_free(bio); if (!pubKey) { freeRSA(); throw Poco::FileException("Failed to load public key", publicKeyFile); } } else { freeRSA(); throw Poco::FileNotFoundException("Public key file", publicKeyFile); } } if (!privateKeyFile.empty()) { BIO* bio = BIO_new(BIO_s_file()); if (!bio) throw Poco::IOException("Cannot create BIO for reading private key", privateKeyFile); int rc = BIO_read_filename(bio, privateKeyFile.c_str()); if (rc) { RSA* privKey = 0; if (privateKeyPassphrase.empty()) privKey = PEM_read_bio_RSAPrivateKey(bio, &_pRSA, 0, 0); else privKey = PEM_read_bio_RSAPrivateKey(bio, &_pRSA, 0, const_cast<char*>(privateKeyPassphrase.c_str())); BIO_free(bio); if (!privKey) { freeRSA(); throw Poco::FileException("Failed to load private key", privateKeyFile); } } else { freeRSA(); throw Poco::FileNotFoundException("Private key file", privateKeyFile); } } }