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;
}
Exemple #2
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;
}
Exemple #3
0
	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");
	}
Exemple #4
0
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;

}
Exemple #5
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;
}
Exemple #6
0
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);
}
Exemple #7
0
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;
}
Exemple #8
0
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);
}
Exemple #9
0
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;
}
Exemple #10
0
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);
	}
Exemple #11
0
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);
}
Exemple #12
0
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;
}
Exemple #13
0
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;
}
Exemple #14
0
/*
  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;
}
Exemple #15
0
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;
}
Exemple #16
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);
}
Exemple #17
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;
    }
Exemple #18
0
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);
}
Exemple #19
0
/* 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;
}
Exemple #20
0
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;
}
Exemple #21
0
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;
}
Exemple #22
0
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;
}
Exemple #23
0
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;
}
Exemple #24
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;
}
Exemple #25
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;
}
Exemple #26
0
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");
      }
    }
    }*/

}
Exemple #27
0
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;
}
Exemple #28
0
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;
    }
Exemple #30
0
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);
		}
	}
}