Пример #1
0
EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
	{
	EVP_PKEY *ret=NULL;

	if (key == NULL) goto error;

	if (key->pkey != NULL)
		{
		return EVP_PKEY_dup(key->pkey);
		}

	if (key->public_key == NULL) goto error;

	if ((ret = EVP_PKEY_new()) == NULL)
		{
		OPENSSL_PUT_ERROR(X509, X509_PUBKEY_get, ERR_R_MALLOC_FAILURE);
		goto error;
		}

	if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm)))
		{
		OPENSSL_PUT_ERROR(X509, X509_PUBKEY_get, X509_R_UNSUPPORTED_ALGORITHM);
		goto error;
		}

	if (ret->ameth->pub_decode)
		{
		if (!ret->ameth->pub_decode(ret, key))
			{
			OPENSSL_PUT_ERROR(X509, X509_PUBKEY_get, X509_R_PUBLIC_KEY_DECODE_ERROR);
			goto error;
			}
		}
	else
		{
		OPENSSL_PUT_ERROR(X509, X509_PUBKEY_get, X509_R_METHOD_NOT_SUPPORTED);
		goto error;
		}

	/* Check to see if another thread set key->pkey first */
	CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
	if (key->pkey)
		{
		CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
		EVP_PKEY_free(ret);
		ret = key->pkey;
		}
	else
		{
		key->pkey = ret;
		CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
		}

	return EVP_PKEY_dup(ret);

	error:
	if (ret != NULL)
		EVP_PKEY_free(ret);
	return(NULL);
	}
Пример #2
0
static int
TA_CTX_set_parameters(TA_CTX *ctx, const CVC_CERT *cert,
        BN_CTX *bn_ctx)
{
    EVP_PKEY *pub;
    int ok = 0, oid;

    check(ctx && cert && cert->body && cert->body->public_key,
            "Invalid arguments");

    /* Extract the public key of the terminal and overwrite the current key. */
    if (ctx->priv_key) {
        pub = EVP_PKEY_dup(ctx->priv_key);
        check(CVC_pubkey2pkey(cert, bn_ctx, pub),
                "Failed to extract public key");
    } else {
        /* ctx->pub might be NULL (in case of a CVCA certificate). */
        pub = CVC_pubkey2pkey(cert, bn_ctx, ctx->pub_key);
        check(pub, "Failed to extract public key");
    }
    ctx->pub_key = pub;

    /* Extract OID from the terminal certificate */
    oid = OBJ_obj2nid(cert->body->public_key->oid);
    check(oid != NID_undef, "Unknown public key format");

    /* Use the oid as the protocol identifier in the TA context */
    ctx->protocol = oid;

    ok = 1;

err:
    return ok;
}
Пример #3
0
EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx) {
  EVP_PKEY_CTX *rctx;

  if (!pctx->pmeth || !pctx->pmeth->copy) {
    return NULL;
  }

  rctx = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
  if (!rctx) {
    return NULL;
  }

  memset(rctx, 0, sizeof(EVP_PKEY_CTX));

  rctx->pmeth = pctx->pmeth;
  rctx->engine = pctx->engine;
  rctx->operation = pctx->operation;

  if (pctx->pkey) {
    rctx->pkey = EVP_PKEY_dup(pctx->pkey);
    if (rctx->pkey == NULL) {
      goto err;
    }
  }

  if (pctx->peerkey) {
    rctx->peerkey = EVP_PKEY_dup(pctx->peerkey);
    if (rctx->peerkey == NULL) {
      goto err;
    }
  }

  if (pctx->pmeth->copy(rctx, pctx) > 0) {
    return rctx;
  }

err:
  EVP_PKEY_CTX_free(rctx);
  OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_dup, ERR_LIB_EVP);
  return NULL;
}
Пример #4
0
KA_CTX *
KA_CTX_dup(const KA_CTX *ka_ctx)
{
    KA_CTX *out = NULL;

    check(ka_ctx, "Invalid arguments");

    out = OPENSSL_malloc(sizeof(KA_CTX));
    if (!out)
        goto err;

    out->key = EVP_PKEY_dup(ka_ctx->key);
    if (!out->key && ka_ctx->key)
        goto err;

    out->md = ka_ctx->md;
    out->md_engine = ka_ctx->md_engine;
    out->cmac_ctx = NULL;
    out->cipher = ka_ctx->cipher;
    out->cipher_engine = ka_ctx->cipher_engine;
    out->iv = NULL;
    out->generate_key = ka_ctx->generate_key;
    out->compute_key = ka_ctx->compute_key;
    out->mac_keylen = ka_ctx->mac_keylen;
    out->enc_keylen = ka_ctx->enc_keylen;
    if (ka_ctx->k_enc) {
        out->k_enc = BUF_MEM_create_init(ka_ctx->k_enc->data, ka_ctx->k_enc->length);
        if (!out->k_enc)
            goto err;
    } else
        out->k_enc = NULL;
    if (ka_ctx->k_mac) {
        out->k_mac = BUF_MEM_create_init(ka_ctx->k_mac->data, ka_ctx->k_mac->length);
        if (!out->k_mac)
            goto err;
    } else
        out->k_mac = NULL;
    if (ka_ctx->shared_secret) {
        out->shared_secret = BUF_MEM_create_init(ka_ctx->shared_secret->data, ka_ctx->shared_secret->length);
        if (!out->shared_secret)
            goto err;
    } else
        out->shared_secret = NULL;

    return out;

err:
    KA_CTX_clear_free(out);

    return NULL;
}
Пример #5
0
static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) {
  EVP_PKEY_CTX *ret;
  const EVP_PKEY_METHOD *pmeth;

  if (id == -1) {
    if (!pkey || !pkey->ameth) {
      return NULL;
    }
    id = pkey->ameth->pkey_id;
  }

  pmeth = evp_pkey_meth_find(id);

  if (pmeth == NULL) {
    OPENSSL_PUT_ERROR(EVP, evp_pkey_ctx_new, EVP_R_UNSUPPORTED_ALGORITHM);
    const char *name = OBJ_nid2sn(id);
    ERR_add_error_dataf("algorithm %d (%s)", id, name);
    return NULL;
  }

  ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
  if (!ret) {
    OPENSSL_PUT_ERROR(EVP, evp_pkey_ctx_new, ERR_R_MALLOC_FAILURE);
    return NULL;
  }
  memset(ret, 0, sizeof(EVP_PKEY_CTX));

  ret->engine = e;
  ret->pmeth = pmeth;
  ret->operation = EVP_PKEY_OP_UNDEFINED;

  if (pkey) {
    ret->pkey = EVP_PKEY_dup(pkey);
  }

  if (pmeth->init) {
    if (pmeth->init(ret) <= 0) {
      if (pkey) {
        EVP_PKEY_free(ret->pkey);
      }
      OPENSSL_free(ret);
      return NULL;
    }
  }

  return ret;
}
Пример #6
0
static EVP_PKEY *
EVP_PKEY_from_pubkey(EVP_PKEY *key, const BUF_MEM *pub, BN_CTX *bn_ctx)
{
    EVP_PKEY *out = NULL;

    check(pub, "Invalid arguments");

    out = EVP_PKEY_dup(key);
    check(out, "");

    if (!EVP_PKEY_set_keys(out, NULL, 0,
                (const unsigned char *) pub->data, pub->length, bn_ctx)) {
        EVP_PKEY_free(out);
        out = NULL;
        goto err;
    }

err:
    return out;
}
Пример #7
0
CERT *ssl_cert_dup(CERT *cert) {
  CERT *ret;
  int i;

  ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
  if (ret == NULL) {
    OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_MALLOC_FAILURE);
    return NULL;
  }

  memset(ret, 0, sizeof(CERT));

  ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]];
  /* or ret->key = ret->pkeys + (cert->key - cert->pkeys), if you find that
   * more readable */

  ret->mask_k = cert->mask_k;
  ret->mask_a = cert->mask_a;

  if (cert->dh_tmp != NULL) {
    ret->dh_tmp = DHparams_dup(cert->dh_tmp);
    if (ret->dh_tmp == NULL) {
      OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_DH_LIB);
      goto err;
    }
    if (cert->dh_tmp->priv_key) {
      BIGNUM *b = BN_dup(cert->dh_tmp->priv_key);
      if (!b) {
        OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_BN_LIB);
        goto err;
      }
      ret->dh_tmp->priv_key = b;
    }
    if (cert->dh_tmp->pub_key) {
      BIGNUM *b = BN_dup(cert->dh_tmp->pub_key);
      if (!b) {
        OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_BN_LIB);
        goto err;
      }
      ret->dh_tmp->pub_key = b;
    }
  }
  ret->dh_tmp_cb = cert->dh_tmp_cb;

  if (cert->ecdh_tmp) {
    ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp);
    if (ret->ecdh_tmp == NULL) {
      OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_EC_LIB);
      goto err;
    }
  }
  ret->ecdh_tmp_cb = cert->ecdh_tmp_cb;
  ret->ecdh_tmp_auto = cert->ecdh_tmp_auto;

  for (i = 0; i < SSL_PKEY_NUM; i++) {
    CERT_PKEY *cpk = cert->pkeys + i;
    CERT_PKEY *rpk = ret->pkeys + i;
    if (cpk->x509 != NULL) {
      rpk->x509 = X509_up_ref(cpk->x509);
    }

    if (cpk->privatekey != NULL) {
      rpk->privatekey = EVP_PKEY_dup(cpk->privatekey);
    }

    if (cpk->chain) {
      rpk->chain = X509_chain_up_ref(cpk->chain);
      if (!rpk->chain) {
        OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_MALLOC_FAILURE);
        goto err;
      }
    }
  }

  /* Peer sigalgs set to NULL as we get these from handshake too */
  ret->peer_sigalgs = NULL;
  ret->peer_sigalgslen = 0;
  /* Configured sigalgs however we copy across */

  if (cert->conf_sigalgs) {
    ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen);
    if (!ret->conf_sigalgs) {
      goto err;
    }
    memcpy(ret->conf_sigalgs, cert->conf_sigalgs, cert->conf_sigalgslen);
    ret->conf_sigalgslen = cert->conf_sigalgslen;
  } else {
    ret->conf_sigalgs = NULL;
  }

  if (cert->client_sigalgs) {
    ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen);
    if (!ret->client_sigalgs) {
      goto err;
    }
    memcpy(ret->client_sigalgs, cert->client_sigalgs, cert->client_sigalgslen);
    ret->client_sigalgslen = cert->client_sigalgslen;
  } else {
    ret->client_sigalgs = NULL;
  }
  /* Shared sigalgs also NULL */
  ret->shared_sigalgs = NULL;
  /* Copy any custom client certificate types */
  if (cert->client_certificate_types) {
    ret->client_certificate_types = BUF_memdup(
        cert->client_certificate_types, cert->num_client_certificate_types);
    if (!ret->client_certificate_types) {
      goto err;
    }
    ret->num_client_certificate_types = cert->num_client_certificate_types;
  }

  ret->cert_flags = cert->cert_flags;

  ret->cert_cb = cert->cert_cb;
  ret->cert_cb_arg = cert->cert_cb_arg;

  if (cert->verify_store) {
    CRYPTO_add(&cert->verify_store->references, 1, CRYPTO_LOCK_X509_STORE);
    ret->verify_store = cert->verify_store;
  }

  if (cert->chain_store) {
    CRYPTO_add(&cert->chain_store->references, 1, CRYPTO_LOCK_X509_STORE);
    ret->chain_store = cert->chain_store;
  }

  ret->ciphers_raw = NULL;

  return ret;

err:
  ssl_cert_free(ret);
  return NULL;
}
Пример #8
0
int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) {
  int ret;
  if (!ctx || !ctx->pmeth ||
      !(ctx->pmeth->derive || ctx->pmeth->encrypt || ctx->pmeth->decrypt) ||
      !ctx->pmeth->ctrl) {
    OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_set_peer,
                      EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
    return 0;
  }
  if (ctx->operation != EVP_PKEY_OP_DERIVE &&
      ctx->operation != EVP_PKEY_OP_ENCRYPT &&
      ctx->operation != EVP_PKEY_OP_DECRYPT) {
    OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_set_peer,
                      EVP_R_OPERATON_NOT_INITIALIZED);
    return 0;
  }

  ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);

  if (ret <= 0) {
    return 0;
  }

  if (ret == 2) {
    return 1;
  }

  if (!ctx->pkey) {
    OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_set_peer, EVP_R_NO_KEY_SET);
    return 0;
  }

  if (ctx->pkey->type != peer->type) {
    OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_set_peer, EVP_R_DIFFERENT_KEY_TYPES);
    return 0;
  }

  /* [email protected]: For clarity.  The error is if parameters in peer are
   * present (!missing) but don't match.  EVP_PKEY_cmp_parameters may return
   * 1 (match), 0 (don't match) and -2 (comparison is not defined).  -1
   * (different key types) is impossible here because it is checked earlier.
   * -2 is OK for us here, as well as 1, so we can check for 0 only. */
  if (!EVP_PKEY_missing_parameters(peer) &&
      !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) {
    OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_set_peer,
                      EVP_R_DIFFERENT_PARAMETERS);
    return 0;
  }

  if (ctx->peerkey) {
    EVP_PKEY_free(ctx->peerkey);
  }
  ctx->peerkey = peer;

  ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);

  if (ret <= 0) {
    ctx->peerkey = NULL;
    return 0;
  }

  EVP_PKEY_dup(peer);
  return 1;
}