コード例 #1
0
ファイル: ssl_cert.c プロジェクト: gengchao/proto-quic
CERT *ssl_cert_dup(CERT *cert) {
  CERT *ret = OPENSSL_malloc(sizeof(CERT));
  if (ret == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    return NULL;
  }
  memset(ret, 0, sizeof(CERT));

  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, ERR_R_DH_LIB);
      goto err;
    }
  }
  ret->dh_tmp_cb = cert->dh_tmp_cb;

  if (cert->x509 != NULL) {
    ret->x509 = X509_up_ref(cert->x509);
  }

  if (cert->privatekey != NULL) {
    ret->privatekey = EVP_PKEY_up_ref(cert->privatekey);
  }

  if (cert->chain) {
    ret->chain = X509_chain_up_ref(cert->chain);
    if (!ret->chain) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
      goto err;
    }
  }

  ret->key_method = cert->key_method;

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

  if (cert->verify_store != NULL) {
    X509_STORE_up_ref(cert->verify_store);
    ret->verify_store = cert->verify_store;
  }

  return ret;

err:
  ssl_cert_free(ret);
  return NULL;
}
コード例 #2
0
ファイル: ssl_cert.c プロジェクト: danielctull-forks/openssl
CERT *ssl_cert_dup(CERT *cert)
{
    CERT *ret = OPENSSL_zalloc(sizeof(*ret));
    int i;

    if (ret == NULL) {
        SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    ret->references = 1;
    ret->key = &ret->pkeys[cert->key - cert->pkeys];
    ret->lock = CRYPTO_THREAD_lock_new();
    if (ret->lock == NULL) {
        SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
        OPENSSL_free(ret);
        return NULL;
    }
#ifndef OPENSSL_NO_DH
    if (cert->dh_tmp != NULL) {
        ret->dh_tmp = cert->dh_tmp;
        EVP_PKEY_up_ref(ret->dh_tmp);
    }
    ret->dh_tmp_cb = cert->dh_tmp_cb;
    ret->dh_tmp_auto = cert->dh_tmp_auto;
#endif

    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 = cpk->x509;
            X509_up_ref(rpk->x509);
        }

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

        if (cpk->chain) {
            rpk->chain = X509_chain_up_ref(cpk->chain);
            if (!rpk->chain) {
                SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
                goto err;
            }
        }
        if (cert->pkeys[i].serverinfo != NULL) {
            /* Just copy everything. */
            ret->pkeys[i].serverinfo =
                OPENSSL_malloc(cert->pkeys[i].serverinfo_length);
            if (ret->pkeys[i].serverinfo == NULL) {
                SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            ret->pkeys[i].serverinfo_length = cert->pkeys[i].serverinfo_length;
            memcpy(ret->pkeys[i].serverinfo,
                   cert->pkeys[i].serverinfo, cert->pkeys[i].serverinfo_length);
        }
    }

    /* Configured sigalgs copied across */
    if (cert->conf_sigalgs) {
        ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen
                                           * sizeof(*cert->conf_sigalgs));
        if (ret->conf_sigalgs == NULL)
            goto err;
        memcpy(ret->conf_sigalgs, cert->conf_sigalgs,
               cert->conf_sigalgslen * sizeof(*cert->conf_sigalgs));
        ret->conf_sigalgslen = cert->conf_sigalgslen;
    } else
        ret->conf_sigalgs = NULL;

    if (cert->client_sigalgs) {
        ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen
                                             * sizeof(*cert->client_sigalgs));
        if (ret->client_sigalgs == NULL)
            goto err;
        memcpy(ret->client_sigalgs, cert->client_sigalgs,
               cert->client_sigalgslen * sizeof(*cert->client_sigalgs));
        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->ctype) {
        ret->ctype = OPENSSL_memdup(cert->ctype, cert->ctype_len);
        if (ret->ctype == NULL)
            goto err;
        ret->ctype_len = cert->ctype_len;
    }

    ret->cert_flags = cert->cert_flags;

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

    if (cert->verify_store) {
        X509_STORE_up_ref(cert->verify_store);
        ret->verify_store = cert->verify_store;
    }

    if (cert->chain_store) {
        X509_STORE_up_ref(cert->chain_store);
        ret->chain_store = cert->chain_store;
    }

    ret->sec_cb = cert->sec_cb;
    ret->sec_level = cert->sec_level;
    ret->sec_ex = cert->sec_ex;

    if (!custom_exts_copy(&ret->custext, &cert->custext))
        goto err;
#ifndef OPENSSL_NO_PSK
    if (cert->psk_identity_hint) {
        ret->psk_identity_hint = OPENSSL_strdup(cert->psk_identity_hint);
        if (ret->psk_identity_hint == NULL)
            goto err;
    }
#endif
    return ret;

 err:
    ssl_cert_free(ret);

    return NULL;
}
コード例 #3
0
ファイル: ssl_cert.c プロジェクト: randombit/hacrypto
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;
}
コード例 #4
0
CERT *ssl_cert_dup(CERT *cert)
{
    CERT *ret;
    int i;

    ret = OPENSSL_malloc(sizeof(CERT));
    if (ret == NULL) {
        SSLerr(SSL_F_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->valid = cert->valid;
    ret->mask_k = cert->mask_k;
    ret->mask_a = cert->mask_a;
    ret->export_mask_k = cert->export_mask_k;
    ret->export_mask_a = cert->export_mask_a;

#ifndef OPENSSL_NO_RSA
    if (cert->rsa_tmp != NULL) {
        RSA_up_ref(cert->rsa_tmp);
        ret->rsa_tmp = cert->rsa_tmp;
    }
    ret->rsa_tmp_cb = cert->rsa_tmp_cb;
#endif

#ifndef OPENSSL_NO_DH
    if (cert->dh_tmp != NULL) {
        ret->dh_tmp = DHparams_dup(cert->dh_tmp);
        if (ret->dh_tmp == NULL) {
            SSLerr(SSL_F_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) {
                SSLerr(SSL_F_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) {
                SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
                goto err;
            }
            ret->dh_tmp->pub_key = b;
        }
    }
    ret->dh_tmp_cb = cert->dh_tmp_cb;
    ret->dh_tmp_auto = cert->dh_tmp_auto;
#endif

#ifndef OPENSSL_NO_EC
    if (cert->ecdh_tmp) {
        ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp);
        if (ret->ecdh_tmp == NULL) {
            SSLerr(SSL_F_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;
#endif

    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 = cpk->x509;
            CRYPTO_add(&rpk->x509->references, 1, CRYPTO_LOCK_X509);
        }

        if (cpk->privatekey != NULL) {
            rpk->privatekey = cpk->privatekey;
            CRYPTO_add(&cpk->privatekey->references, 1, CRYPTO_LOCK_EVP_PKEY);
        }

        if (cpk->chain) {
            rpk->chain = X509_chain_up_ref(cpk->chain);
            if (!rpk->chain) {
                SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
                goto err;
            }
        }
        rpk->valid_flags = 0;
#ifndef OPENSSL_NO_TLSEXT
        if (cert->pkeys[i].serverinfo != NULL) {
            /* Just copy everything. */
            ret->pkeys[i].serverinfo =
                OPENSSL_malloc(cert->pkeys[i].serverinfo_length);
            if (ret->pkeys[i].serverinfo == NULL) {
                SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            ret->pkeys[i].serverinfo_length =
                cert->pkeys[i].serverinfo_length;
            memcpy(ret->pkeys[i].serverinfo,
                   cert->pkeys[i].serverinfo,
                   cert->pkeys[i].serverinfo_length);
        }
#endif
    }

    ret->references = 1;
    /*
     * Set digests to defaults. NB: we don't copy existing values as they
     * will be set during handshake.
     */
    ssl_cert_set_default_md(ret);
    /* 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->ctypes) {
        ret->ctypes = OPENSSL_malloc(cert->ctype_num);
        if (!ret->ctypes)
            goto err;
        memcpy(ret->ctypes, cert->ctypes, cert->ctype_num);
        ret->ctype_num = cert->ctype_num;
    }

    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;

    ret->sec_cb = cert->sec_cb;
    ret->sec_level = cert->sec_level;
    ret->sec_ex = cert->sec_ex;

#ifndef OPENSSL_NO_TLSEXT
    if (!custom_exts_copy(&ret->cli_ext, &cert->cli_ext))
        goto err;
    if (!custom_exts_copy(&ret->srv_ext, &cert->srv_ext))
        goto err;
#endif

    return (ret);

 err:
    ssl_cert_free(ret);

    return NULL;
}
コード例 #5
0
ファイル: ssl_cert.c プロジェクト: 0culus/openssl
CERT *ssl_cert_dup(CERT *cert)
	{
	CERT *ret;
	int i;

	ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
	if (ret == NULL)
		{
		SSLerr(SSL_F_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->valid = cert->valid;
	ret->mask_k = cert->mask_k;
	ret->mask_a = cert->mask_a;
	ret->export_mask_k = cert->export_mask_k;
	ret->export_mask_a = cert->export_mask_a;

#ifndef OPENSSL_NO_RSA
	if (cert->rsa_tmp != NULL)
		{
		RSA_up_ref(cert->rsa_tmp);
		ret->rsa_tmp = cert->rsa_tmp;
		}
	ret->rsa_tmp_cb = cert->rsa_tmp_cb;
#endif

#ifndef OPENSSL_NO_DH
	if (cert->dh_tmp != NULL)
		{
		ret->dh_tmp = DHparams_dup(cert->dh_tmp);
		if (ret->dh_tmp == NULL)
			{
			SSLerr(SSL_F_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)
				{
				SSLerr(SSL_F_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)
				{
				SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
				goto err;
				}
			ret->dh_tmp->pub_key = b;
			}
		}
	ret->dh_tmp_cb = cert->dh_tmp_cb;
	ret->dh_tmp_auto = cert->dh_tmp_auto;
#endif

#ifndef OPENSSL_NO_ECDH
	if (cert->ecdh_tmp)
		{
		ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp);
		if (ret->ecdh_tmp == NULL)
			{
			SSLerr(SSL_F_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;
#endif

	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 = cpk->x509;
			CRYPTO_add(&rpk->x509->references, 1, CRYPTO_LOCK_X509);
			}
		
		if (cpk->privatekey != NULL)
			{
			rpk->privatekey = cpk->privatekey;
			CRYPTO_add(&cpk->privatekey->references, 1,
				CRYPTO_LOCK_EVP_PKEY);

			switch(i) 
				{
				/* If there was anything special to do for
				 * certain types of keys, we'd do it here.
				 * (Nothing at the moment, I think.) */

			case SSL_PKEY_RSA_ENC:
			case SSL_PKEY_RSA_SIGN:
				/* We have an RSA key. */
				break;
				
			case SSL_PKEY_DSA_SIGN:
				/* We have a DSA key. */
				break;
				
			case SSL_PKEY_DH_RSA:
			case SSL_PKEY_DH_DSA:
				/* We have a DH key. */
				break;

			case SSL_PKEY_ECC:
				/* We have an ECC key */
				break;

			default:
				/* Can't happen. */
				SSLerr(SSL_F_SSL_CERT_DUP, SSL_R_LIBRARY_BUG);
				}
			}

		if (cpk->chain)
			{
			rpk->chain = X509_chain_up_ref(cpk->chain);
			if (!rpk->chain)
				{
				SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
				goto err;
				}
			}
		rpk->valid_flags = 0;
#ifndef OPENSSL_NO_TLSEXT
		if (cert->pkeys[i].serverinfo != NULL)
			{
			/* Just copy everything. */
			ret->pkeys[i].serverinfo =
				OPENSSL_malloc(cert->pkeys[i].serverinfo_length);
			if (ret->pkeys[i].serverinfo == NULL)
				{
				SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
				return NULL;
				}
			ret->pkeys[i].serverinfo_length =
				cert->pkeys[i].serverinfo_length;
			memcpy(ret->pkeys[i].serverinfo,
			       cert->pkeys[i].serverinfo,
			       cert->pkeys[i].serverinfo_length);
			}
#endif
		}
	
	ret->references=1;
	/* Set digests to defaults. NB: we don't copy existing values as they
	 * will be set during handshake.
	 */
	ssl_cert_set_default_md(ret);
	/* 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->ctypes)
		{
		ret->ctypes = OPENSSL_malloc(cert->ctype_num);
		if (!ret->ctypes)
			goto err;
		memcpy(ret->ctypes, cert->ctypes, cert->ctype_num);
		ret->ctype_num = cert->ctype_num;
		}

	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;

	ret->sec_cb = cert->sec_cb;
	ret->sec_level = cert->sec_level;
	ret->sec_ex = cert->sec_ex;

	return(ret);
	
#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
err:
#endif
#ifndef OPENSSL_NO_RSA
	if (ret->rsa_tmp != NULL)
		RSA_free(ret->rsa_tmp);
#endif
#ifndef OPENSSL_NO_DH
	if (ret->dh_tmp != NULL)
		DH_free(ret->dh_tmp);
#endif
#ifndef OPENSSL_NO_ECDH
	if (ret->ecdh_tmp != NULL)
		EC_KEY_free(ret->ecdh_tmp);
#endif

	ssl_cert_clear_certs(ret);

	return NULL;
	}
コード例 #6
0
ファイル: ssl_cert.c プロジェクト: luocn99/tgw-boringssl
CERT *ssl_cert_dup(CERT *cert) {
  CERT *ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
  if (ret == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    return NULL;
  }
  memset(ret, 0, sizeof(CERT));

  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, 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, 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, ERR_R_BN_LIB);
        goto err;
      }
      ret->dh_tmp->pub_key = b;
    }
  }
  ret->dh_tmp_cb = cert->dh_tmp_cb;

  ret->ecdh_nid = cert->ecdh_nid;
  ret->ecdh_tmp_cb = cert->ecdh_tmp_cb;

  if (cert->x509 != NULL) {
    ret->x509 = X509_up_ref(cert->x509);
  }

  if (cert->privatekey != NULL) {
    ret->privatekey = EVP_PKEY_up_ref(cert->privatekey);
  }

  if (cert->chain) {
    ret->chain = X509_chain_up_ref(cert->chain);
    if (!ret->chain) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
      goto err;
    }
  }

  /* Copy over signature algorithm configuration. */
  if (cert->conf_sigalgs) {
    ret->conf_sigalgs = BUF_memdup(cert->conf_sigalgs, cert->conf_sigalgslen);
    if (!ret->conf_sigalgs) {
      goto err;
    }
    ret->conf_sigalgslen = cert->conf_sigalgslen;
  }

  if (cert->client_sigalgs) {
    ret->client_sigalgs = BUF_memdup(cert->client_sigalgs,
                                     cert->client_sigalgslen);
    if (!ret->client_sigalgs) {
      goto err;
    }
    ret->client_sigalgslen = cert->client_sigalgslen;
  }

  /* 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_cb = cert->cert_cb;
  ret->cert_cb_arg = cert->cert_cb_arg;

  if (cert->verify_store) {
    CRYPTO_refcount_inc(&cert->verify_store->references);
    ret->verify_store = cert->verify_store;
  }

  if (cert->chain_store) {
    CRYPTO_refcount_inc(&cert->chain_store->references);
    ret->chain_store = cert->chain_store;
  }

  return ret;

err:
  ssl_cert_free(ret);
  return NULL;
}
コード例 #7
0
ファイル: ssl_cert.c プロジェクト: benlaurie/openssl-old-2
CERT *ssl_cert_dup(CERT *cert)
{
    CERT *ret = OPENSSL_zalloc(sizeof(*ret));
    int i;

    if (ret == NULL) {
        SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
        return (NULL);
    }

    ret->references = 1;
    ret->key = &ret->pkeys[cert->key - cert->pkeys];

#ifndef OPENSSL_NO_DH
    if (cert->dh_tmp != NULL) {
        ret->dh_tmp = DHparams_dup(cert->dh_tmp);
        if (ret->dh_tmp == NULL) {
            SSLerr(SSL_F_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) {
                SSLerr(SSL_F_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) {
                SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
                goto err;
            }
            ret->dh_tmp->pub_key = b;
        }
    }
    ret->dh_tmp_cb = cert->dh_tmp_cb;
    ret->dh_tmp_auto = cert->dh_tmp_auto;
#endif

    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 = cpk->x509;
            X509_up_ref(rpk->x509);
        }

        if (cpk->privatekey != NULL) {
            rpk->privatekey = cpk->privatekey;
            CRYPTO_add(&cpk->privatekey->references, 1, CRYPTO_LOCK_EVP_PKEY);
        }

        if (cpk->chain) {
            rpk->chain = X509_chain_up_ref(cpk->chain);
            if (!rpk->chain) {
                SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
                goto err;
            }
        }
        if (cert->pkeys[i].serverinfo != NULL) {
            /* Just copy everything. */
            ret->pkeys[i].serverinfo =
                OPENSSL_malloc(cert->pkeys[i].serverinfo_length);
            if (ret->pkeys[i].serverinfo == NULL) {
                SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            ret->pkeys[i].serverinfo_length =
                cert->pkeys[i].serverinfo_length;
            memcpy(ret->pkeys[i].serverinfo,
                   cert->pkeys[i].serverinfo,
                   cert->pkeys[i].serverinfo_length);
        }
    }

    /* Configured sigalgs copied across */
    if (cert->conf_sigalgs) {
        ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen);
        if (ret->conf_sigalgs == NULL)
            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 == NULL)
            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->ctypes) {
        ret->ctypes = OPENSSL_malloc(cert->ctype_num);
        if (ret->ctypes == NULL)
            goto err;
        memcpy(ret->ctypes, cert->ctypes, cert->ctype_num);
        ret->ctype_num = cert->ctype_num;
    }

    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->sec_cb = cert->sec_cb;
    ret->sec_level = cert->sec_level;
    ret->sec_ex = cert->sec_ex;

    if (!custom_exts_copy(&ret->cli_ext, &cert->cli_ext))
        goto err;
    if (!custom_exts_copy(&ret->srv_ext, &cert->srv_ext))
        goto err;
#ifndef OPENSSL_NO_PSK
    if (cert->psk_identity_hint) {
        ret->psk_identity_hint = OPENSSL_strdup(cert->psk_identity_hint);
        if (ret->psk_identity_hint == NULL)
            goto err;
    }
#endif
    return (ret);

 err:
    ssl_cert_free(ret);

    return NULL;
}
コード例 #8
0
ファイル: ssl_sess.c プロジェクト: infinityhacks/openssl
/*
 * Create a new SSL_SESSION and duplicate the contents of |src| into it. If
 * ticket == 0 then no ticket information is duplicated, otherwise it is.
 */
SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
{
    SSL_SESSION *dest;

    dest = OPENSSL_malloc(sizeof(*src));
    if (dest == NULL) {
        goto err;
    }
    memcpy(dest, src, sizeof(*dest));

    /*
     * Set the various pointers to NULL so that we can call SSL_SESSION_free in
     * the case of an error whilst halfway through constructing dest
     */
#ifndef OPENSSL_NO_PSK
    dest->psk_identity_hint = NULL;
    dest->psk_identity = NULL;
#endif
    dest->ciphers = NULL;
    dest->ext.hostname = NULL;
#ifndef OPENSSL_NO_EC
    dest->ext.ecpointformats = NULL;
    dest->ext.supportedgroups = NULL;
#endif
    dest->ext.tick = NULL;
#ifndef OPENSSL_NO_SRP
    dest->srp_username = NULL;
#endif
    memset(&dest->ex_data, 0, sizeof(dest->ex_data));

    /* We deliberately don't copy the prev and next pointers */
    dest->prev = NULL;
    dest->next = NULL;

    dest->references = 1;

    dest->lock = CRYPTO_THREAD_lock_new();
    if (dest->lock == NULL)
        goto err;

    if (src->peer != NULL)
        X509_up_ref(src->peer);

    if (src->peer_chain != NULL) {
        dest->peer_chain = X509_chain_up_ref(src->peer_chain);
        if (dest->peer_chain == NULL)
            goto err;
    }
#ifndef OPENSSL_NO_PSK
    if (src->psk_identity_hint) {
        dest->psk_identity_hint = OPENSSL_strdup(src->psk_identity_hint);
        if (dest->psk_identity_hint == NULL) {
            goto err;
        }
    }
    if (src->psk_identity) {
        dest->psk_identity = OPENSSL_strdup(src->psk_identity);
        if (dest->psk_identity == NULL) {
            goto err;
        }
    }
#endif

    if (src->ciphers != NULL) {
        dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers);
        if (dest->ciphers == NULL)
            goto err;
    }

    if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION,
                            &dest->ex_data, &src->ex_data)) {
        goto err;
    }

    if (src->ext.hostname) {
        dest->ext.hostname = OPENSSL_strdup(src->ext.hostname);
        if (dest->ext.hostname == NULL) {
            goto err;
        }
    }
#ifndef OPENSSL_NO_EC
    if (src->ext.ecpointformats) {
        dest->ext.ecpointformats =
            OPENSSL_memdup(src->ext.ecpointformats,
                           src->ext.ecpointformats_len);
        if (dest->ext.ecpointformats == NULL)
            goto err;
    }
    if (src->ext.supportedgroups) {
        dest->ext.supportedgroups =
            OPENSSL_memdup(src->ext.supportedgroups,
                           src->ext.supportedgroups_len);
        if (dest->ext.supportedgroups == NULL)
            goto err;
    }
#endif

    if (ticket != 0) {
        dest->ext.tick =
            OPENSSL_memdup(src->ext.tick, src->ext.ticklen);
        if (dest->ext.tick == NULL)
            goto err;
    } else {
        dest->ext.tick_lifetime_hint = 0;
        dest->ext.ticklen = 0;
    }

#ifndef OPENSSL_NO_SRP
    if (src->srp_username) {
        dest->srp_username = OPENSSL_strdup(src->srp_username);
        if (dest->srp_username == NULL) {
            goto err;
        }
    }
#endif

    return dest;
 err:
    SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE);
    SSL_SESSION_free(dest);
    return NULL;
}
コード例 #9
0
ファイル: ssl_cert.c プロジェクト: libressl-portable/openbsd
CERT *
ssl_cert_dup(CERT *cert)
{
	CERT *ret;
	int i;

	ret = calloc(1, sizeof(CERT));
	if (ret == NULL) {
		SSLerrorx(ERR_R_MALLOC_FAILURE);
		return (NULL);
	}

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

	ret->valid = cert->valid;
	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) {
			SSLerrorx(ERR_R_DH_LIB);
			goto err;
		}
		if (cert->dh_tmp->priv_key) {
			BIGNUM *b = BN_dup(cert->dh_tmp->priv_key);
			if (!b) {
				SSLerrorx(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) {
				SSLerrorx(ERR_R_BN_LIB);
				goto err;
			}
			ret->dh_tmp->pub_key = b;
		}
	}
	ret->dh_tmp_cb = cert->dh_tmp_cb;
	ret->dh_tmp_auto = cert->dh_tmp_auto;

	for (i = 0; i < SSL_PKEY_NUM; i++) {
		if (cert->pkeys[i].x509 != NULL) {
			ret->pkeys[i].x509 = cert->pkeys[i].x509;
			CRYPTO_add(&ret->pkeys[i].x509->references, 1,
			CRYPTO_LOCK_X509);
		}

		if (cert->pkeys[i].privatekey != NULL) {
			ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
			CRYPTO_add(&ret->pkeys[i].privatekey->references, 1,
			CRYPTO_LOCK_EVP_PKEY);

			switch (i) {
				/*
				 * If there was anything special to do for
				 * certain types of keys, we'd do it here.
				 * (Nothing at the moment, I think.)
				 */

			case SSL_PKEY_RSA_ENC:
			case SSL_PKEY_RSA_SIGN:
				/* We have an RSA key. */
				break;

			case SSL_PKEY_DH_RSA:
				/* We have a DH key. */
				break;

			case SSL_PKEY_ECC:
				/* We have an ECC key */
				break;

			default:
				/* Can't happen. */
				SSLerrorx(SSL_R_LIBRARY_BUG);
			}
		}

		if (cert->pkeys[i].chain != NULL) {
			if ((ret->pkeys[i].chain =
			    X509_chain_up_ref(cert->pkeys[i].chain)) == NULL)
				goto err;
		}
	}

	/*
	 * ret->extra_certs *should* exist, but currently the own certificate
	 * chain is held inside SSL_CTX
	 */

	ret->references = 1;

	return (ret);

 err:
	DH_free(ret->dh_tmp);

	for (i = 0; i < SSL_PKEY_NUM; i++) {
		X509_free(ret->pkeys[i].x509);
		EVP_PKEY_free(ret->pkeys[i].privatekey);
		sk_X509_pop_free(ret->pkeys[i].chain, X509_free);
	}
	free (ret);
	return NULL;
}
コード例 #10
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 = cpk->privatekey;
			CRYPTO_add(&cpk->privatekey->references, 1,
				CRYPTO_LOCK_EVP_PKEY);

			switch(i) 
				{
				/* If there was anything special to do for
				 * certain types of keys, we'd do it here.
				 * (Nothing at the moment, I think.) */

			case SSL_PKEY_RSA_ENC:
			case SSL_PKEY_RSA_SIGN:
				/* We have an RSA key. */
				break;
				
			case SSL_PKEY_ECC:
				/* We have an ECC key */
				break;

			default:
				/* Can't happen. */
				OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, SSL_R_LIBRARY_BUG);
				}
			}

		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;
	}