예제 #1
0
/*
 *  call-seq:
 *     OpenSSL::PKey.read(string [, pwd ] ) -> PKey
 *     OpenSSL::PKey.read(file [, pwd ]) -> PKey
 *
 * === Parameters
 * * +string+ is a DER- or PEM-encoded string containing an arbitrary private
 * or public key.
 * * +file+ is an instance of +File+ containing a DER- or PEM-encoded
 * arbitrary private or public key.
 * * +pwd+ is an optional password in case +string+ or +file+ is an encrypted
 * PEM resource.
 */
static VALUE
ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
{
     EVP_PKEY *pkey;
     BIO *bio;
     VALUE data, pass;
     char *passwd = NULL;

     rb_scan_args(argc, argv, "11", &data, &pass);

     bio = ossl_obj2bio(data);
     if (!(pkey = d2i_PrivateKey_bio(bio, NULL))) {
	OSSL_BIO_reset(bio);
	if (!NIL_P(pass)) {
	    passwd = StringValuePtr(pass);
	}
	if (!(pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, passwd))) {
	    OSSL_BIO_reset(bio);
	    if (!(pkey = d2i_PUBKEY_bio(bio, NULL))) {
		OSSL_BIO_reset(bio);
		if (!NIL_P(pass)) {
		    passwd = StringValuePtr(pass);
		}
		pkey = PEM_read_bio_PUBKEY(bio, NULL, ossl_pem_passwd_cb, passwd);
	    }
	}
    }

    BIO_free(bio);
    if (!pkey)
	ossl_raise(rb_eArgError, "Could not parse PKey");
    return ossl_pkey_new(pkey);
}
예제 #2
0
파일: keys.c 프로젝트: cran/openssl
SEXP R_pubkey_bitsize(SEXP input){
  BIO *mem = BIO_new_mem_buf(RAW(input), LENGTH(input));
  EVP_PKEY *pkey = d2i_PUBKEY_bio(mem, NULL);
  BIO_free(mem);
  if(!pkey)
    return R_NilValue;
  int size = 0;
  const BIGNUM * val;
  switch(EVP_PKEY_base_id(pkey)){
  case EVP_PKEY_RSA:
    MY_RSA_get0_key(EVP_PKEY_get1_RSA(pkey), &val, NULL, NULL);
    size = BN_num_bits(val);
    break;
  case EVP_PKEY_DSA:
    MY_DSA_get0_pqg(EVP_PKEY_get1_DSA(pkey), &val, NULL, NULL);
    size = BN_num_bits(val);
    break;
#ifndef OPENSSL_NO_EC
  case EVP_PKEY_EC:
    size = ec_bitsize(EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get1_EC_KEY(pkey))));
    break;
#endif //OPENSSL_NO_EC
  default:
    Rf_error("Unsupported key type: %d", EVP_PKEY_base_id(pkey));
  }
  EVP_PKEY_free(pkey);
  return ScalarInteger(size);
}
예제 #3
0
파일: csr.c 프로젝트: LuaDist2/bkopenssl
static LUA_FUNCTION(openssl_csr_sign)
{
  X509_REQ * csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req");
  luaL_argcheck(L, csr->req_info->pubkey, 1, "has not set public key!!!");
  if (auxiliar_isclass(L, "openssl.evp_pkey", 2))
  {
    EVP_PKEY *pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey");
    const EVP_MD* md = lua_isnone(L, 3) ? EVP_get_digestbyname("sha1") : get_digest(L, 3);
    int ret = 1;
    if (X509_REQ_get_pubkey(csr) == NULL)
    {
      BIO* bio = BIO_new(BIO_s_mem());
      if ( ret = i2d_PUBKEY_bio(bio, pkey))
      {
        ret = X509_REQ_set_pubkey(csr, d2i_PUBKEY_bio(bio, NULL));
      }
      BIO_free(bio);
    }
    if (ret == 1)
      ret = X509_REQ_sign(csr, pkey, md);
    return openssl_pushresult(L, ret);
  }
  else if (lua_isstring(L, 2))
  {
    size_t siglen;
    const unsigned char* sigdata = (const unsigned char*)luaL_checklstring(L, 2, &siglen);
    const EVP_MD* md = get_digest(L, 3);

    /* (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) ? V_ASN1_NULL : V_ASN1_UNDEF, */
    X509_ALGOR_set0(csr->sig_alg, OBJ_nid2obj(md->pkey_type), V_ASN1_NULL, NULL);

    if (csr->signature->data != NULL)
      OPENSSL_free(csr->signature->data);
    csr->signature->data = OPENSSL_malloc(siglen);
    memcpy(csr->signature->data, sigdata, siglen);
    csr->signature->length = siglen;
    /*
    * In the interests of compatibility, I'll make sure that the bit string
    * has a 'not-used bits' value of 0
    */
    csr->signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
    csr->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
    lua_pushboolean(L, 1);
    return 1;
  }
  else
  {
    unsigned char* tosign = NULL;
    const ASN1_ITEM *it = ASN1_ITEM_rptr(X509_REQ_INFO);
    int inl = ASN1_item_i2d((void*)csr->req_info, &tosign, it);
    if (inl > 0 && tosign)
    {
      lua_pushlstring(L, (const char*)tosign, inl);
      OPENSSL_free(tosign);
      return 1;
    }
    return openssl_pushresult(L, 0);
  }
}
예제 #4
0
static int verify_pubkey(X509* cert, const char *key, size_t key_size)
{
    EVP_PKEY* cert_pubkey = NULL;
    EVP_PKEY* orig_pubkey = NULL;
    BIO* bio = NULL;
    int ret = 0;

    if (!key || key_size == 0)
        return 0;

    if (!cert) {
        SPICE_DEBUG("warning: no cert!");
        return 0;
    }

    cert_pubkey = X509_get_pubkey(cert);
    if (!cert_pubkey) {
        SPICE_DEBUG("warning: reading public key from certificate failed");
        goto finish;
    }

    bio = BIO_new_mem_buf((void*)key, key_size);
    if (!bio) {
        SPICE_DEBUG("creating BIO failed");
        goto finish;
    }

    orig_pubkey = d2i_PUBKEY_bio(bio, NULL);
    if (!orig_pubkey) {
        SPICE_DEBUG("reading pubkey from bio failed");
        goto finish;
    }

    ret = EVP_PKEY_cmp(orig_pubkey, cert_pubkey);

    if (ret == 1)
        SPICE_DEBUG("public keys match");
    else if (ret == 0)
        SPICE_DEBUG("public keys mismatch");
    else
        SPICE_DEBUG("public keys types mismatch");

finish:
    if (bio)
        BIO_free(bio);

    if (orig_pubkey)
        EVP_PKEY_free(orig_pubkey);

    if (cert_pubkey)
        EVP_PKEY_free(cert_pubkey);

    return ret;
}
예제 #5
0
int cipher_rsa_encrypt(const char *plaintext,
		       const struct public_key *public_key,
		       unsigned char *out_crypttext, size_t *out_len)
{
	EVP_PKEY *pubkey = NULL;
	RSA *rsa = NULL;
	BIO *memory = NULL;
	int ret;

	if (*out_len < public_key->len) {
		ret = -EINVAL;
		goto out;
	}

	memory = BIO_new(BIO_s_mem());
	ret = BIO_write(memory, public_key->key, public_key->len);
	if (ret < 0)
		goto out;

	ret = -EIO;
	pubkey = d2i_PUBKEY_bio(memory, NULL);
	if (!pubkey)
		goto out;

	rsa = EVP_PKEY_get1_RSA(pubkey);
	if (!rsa)
		goto out;

	ret = RSA_public_encrypt(strlen(plaintext), (unsigned char *) plaintext,
			         (unsigned char *) out_crypttext,
			         rsa, RSA_PKCS1_OAEP_PADDING);
	if (ret < 0)
		goto out;

	*out_len = ret;
	ret = 0;

out:
	EVP_PKEY_free(pubkey);
	RSA_free(rsa);
	BIO_free_all(memory);
	return ret;
}
예제 #6
0
static EP_CRYPTO_KEY *
key_read_bio(BIO *bio,
		const char *filename,
		int keyform,
		uint32_t flags)
{
	EVP_PKEY *key = NULL;
	const char *pubsec = EP_UT_BITSET(EP_CRYPTO_F_SECRET, flags) ?
		"secret" : "public";

	ep_dbg_cprintf(Dbg, 20, "key_read_bio: name %s, form %d, flags %x\n",
			filename, keyform, flags);
	EP_ASSERT(bio != NULL);
	if (keyform <= 0)
		return _ep_crypto_error("keyform must be specified");

	if (keyform == EP_CRYPTO_KEYFORM_PEM)
	{
		// easy case
		if (EP_UT_BITSET(EP_CRYPTO_F_SECRET, flags))
			key = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
		else
			key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
	}
	else if (keyform == EP_CRYPTO_KEYFORM_DER)
	{
		if (EP_UT_BITSET(EP_CRYPTO_F_SECRET, flags))
			key = d2i_PrivateKey_bio(bio, NULL);
		else
			key = d2i_PUBKEY_bio(bio, NULL);
	}
	else
	{
		return _ep_crypto_error("unknown key format %d", keyform);
	}

	if (key == NULL)
		return _ep_crypto_error("cannot read %s key from %s",
				pubsec, filename);
	return key;
}
예제 #7
0
PublicKey::PublicKey(ByteArray &derEncoded)
		throw (EncodeException) : AsymmetricKey(NULL)
{
	/* DER format support only RSA, DSA and EC. DH isn't supported */
	BIO *buffer;
	buffer = BIO_new(BIO_s_mem());
	if (buffer == NULL)
	{
		throw EncodeException(EncodeException::BUFFER_CREATING, "PublicKey::PublicKey");
	}
	if ((unsigned int)(BIO_write(buffer, derEncoded.getDataPointer(), derEncoded.size())) != derEncoded.size())
	{
		BIO_free(buffer);
		throw EncodeException(EncodeException::BUFFER_WRITING, "PublicKey::PublicKey");
	}
	this->key = d2i_PUBKEY_bio(buffer, NULL); /* TODO: will the second parameter work fine ? */
	if (this->key == NULL)
	{
		BIO_free(buffer);
		throw EncodeException(EncodeException::DER_DECODE, "PublicKey::PublicKey");
	}
	BIO_free(buffer);
}
예제 #8
0
파일: keys.c 프로젝트: cran/openssl
SEXP R_pubkey_type(SEXP input){
  BIO *mem = BIO_new_mem_buf(RAW(input), LENGTH(input));
  EVP_PKEY *pkey = d2i_PUBKEY_bio(mem, NULL);
  BIO_free(mem);
  if(!pkey)
    return R_NilValue;
  char *keytype;
  switch(EVP_PKEY_base_id(pkey)){
  case EVP_PKEY_RSA:
    keytype = "rsa";
    break;
  case EVP_PKEY_DSA:
    keytype = "dsa";
    break;
  case EVP_PKEY_EC:
    keytype = "ecdsa";
    break;
  default:
    Rf_error("Unsupported key type: %d", EVP_PKEY_base_id(pkey));
  }
  EVP_PKEY_free(pkey);
  return mkString(keytype);
}
/* coroutine context */
static void spice_channel_send_auth(SpiceChannel *channel)
{
    spice_channel *c = channel->priv;
    EVP_PKEY *pubkey;
    int nRSASize;
    BIO *bioKey;
    RSA *rsa;
    char *password;
    uint8_t *encrypted;
    int rc;

    bioKey = BIO_new(BIO_s_mem());
    g_return_if_fail(bioKey != NULL);

    BIO_write(bioKey, c->peer_msg->pub_key, SPICE_TICKET_PUBKEY_BYTES);
    pubkey = d2i_PUBKEY_bio(bioKey, NULL);
    rsa = pubkey->pkey.rsa;
    nRSASize = RSA_size(rsa);

    encrypted = g_alloca(nRSASize);
    /*
      The use of RSA encryption limit the potential maximum password length.
      for RSA_PKCS1_OAEP_PADDING it is RSA_size(rsa) - 41.
    */
    g_object_get(c->session, "password", &password, NULL);
    if (password == NULL)
        password = g_strdup("");
    rc = RSA_public_encrypt(strlen(password) + 1, (uint8_t*)password,
                            encrypted, rsa, RSA_PKCS1_OAEP_PADDING);
    g_warn_if_fail(rc > 0);

    spice_channel_write(channel, encrypted, nRSASize);
    memset(encrypted, 0, nRSASize);
    BIO_free(bioKey);
    g_free(password);
}
예제 #10
0
static EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
	const char *pass, ENGINE *e, const char *key_descrip)
{
	BIO *key=NULL;
	EVP_PKEY *pkey=NULL;
	PW_CB_DATA cb_data;

	cb_data.password = pass;
	cb_data.prompt_info = file;

	if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE))
	{
		BIO_printf(err,"no keyfile specified\n");
		goto end;
	}
#ifndef OPENSSL_NO_ENGINE
	if (format == FORMAT_ENGINE)
	{
		if (!e)
			BIO_printf(bio_err,"no engine specified\n");
		else
			pkey = ENGINE_load_public_key(e, file,
			ui_method, &cb_data);
		goto end;
	}
#endif
	key=BIO_new(BIO_s_file());
	if (key == NULL)
	{
		ERR_print_errors(err);
		goto end;
	}
	if (file == NULL && maybe_stdin)
	{
		setvbuf(stdin, NULL, _IONBF, 0);
		BIO_set_fp(key,stdin,BIO_NOCLOSE);
	}
	else if (BIO_read_filename(key,file) <= 0)
	{
		BIO_printf(err, "Error opening %s %s\n",
			key_descrip, file);
		ERR_print_errors(err);
		goto end;
	}

	if (format == FORMAT_ASN1)
	{
		pkey=d2i_PUBKEY_bio(key, NULL);
	}
	else if (format == FORMAT_PEM)
	{
		pkey=PEM_read_bio_PUBKEY(key,NULL,
			(pem_password_cb *)password_callback, &cb_data);
	}
#if defined(PACS_USING_FORMAT_NETSCAPE_OR_PKCS12)
#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
	else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
		pkey = load_netscape_key(err, key, file, key_descrip, format);
#endif
#endif
	else
	{
		BIO_printf(err,"bad input format specified for key file\n");
		goto end;
	}
end:
	if (key != NULL) BIO_free(key);
	if (pkey == NULL)
		BIO_printf(err,"unable to load %s\n", key_descrip);
	return(pkey);
}
예제 #11
0
파일: app.c 프로젝트: symma/xmlsec
/**
 * xmlSecOpenSSLAppKeyLoadBIO:
 * @bio:                the key BIO.
 * @format:             the key file format.
 * @pwd:                the key file password.
 * @pwdCallback:        the key password callback.
 * @pwdCallbackCtx:     the user context for password callback.
 *
 * Reads key from the an OpenSSL BIO object.
 *
 * Returns: pointer to the key or NULL if an error occurs.
 */
xmlSecKeyPtr
xmlSecOpenSSLAppKeyLoadBIO(BIO* bio, xmlSecKeyDataFormat format,
                        const char *pwd, void* pwdCallback,
                        void* pwdCallbackCtx) {

    xmlSecKeyPtr key = NULL;
    xmlSecKeyDataPtr data;
    EVP_PKEY* pKey = NULL;
    int ret;

    xmlSecAssert2(bio != NULL, NULL);
    xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL);

    switch(format) {
    case xmlSecKeyDataFormatPem:
        /* try to read private key first */
        if(pwd != NULL) {
            pKey = PEM_read_bio_PrivateKey(bio, NULL,
                        xmlSecOpenSSLDummyPasswordCallback,
                        (void*)pwd);
        } else {
            pKey = PEM_read_bio_PrivateKey(bio, NULL,
                            XMLSEC_PTR_TO_FUNC(pem_password_cb, pwdCallback),
                            pwdCallbackCtx);
        }
        if(pKey == NULL) {
            /* go to start of the file and try to read public key */
            (void)BIO_reset(bio);
            pKey = PEM_read_bio_PUBKEY(bio, NULL,
                            XMLSEC_PTR_TO_FUNC(pem_password_cb, pwdCallback),
                            pwdCallbackCtx);
            if(pKey == NULL) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            NULL,
                            "PEM_read_bio_PrivateKey and PEM_read_bio_PUBKEY",
                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
                            XMLSEC_ERRORS_NO_MESSAGE);
                return(NULL);
            }
        }
        break;
    case xmlSecKeyDataFormatDer:
        /* try to read private key first */
        pKey = d2i_PrivateKey_bio(bio, NULL);
        if(pKey == NULL) {
            /* go to start of the file and try to read public key */
            (void)BIO_reset(bio);
            pKey = d2i_PUBKEY_bio(bio, NULL);
            if(pKey == NULL) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            NULL,
                            "d2i_PrivateKey_bio and d2i_PUBKEY_bio",
                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
                            XMLSEC_ERRORS_NO_MESSAGE);
                return(NULL);
            }
        }
        break;
    case xmlSecKeyDataFormatPkcs8Pem:
        /* try to read private key first */
        pKey = PEM_read_bio_PrivateKey(bio, NULL,
                            XMLSEC_PTR_TO_FUNC(pem_password_cb, pwdCallback),
                            pwdCallbackCtx);
        if(pKey == NULL) {
            xmlSecError(XMLSEC_ERRORS_HERE,
                        NULL,
                        "PEM_read_bio_PrivateKey",
                        XMLSEC_ERRORS_R_CRYPTO_FAILED,
                        XMLSEC_ERRORS_NO_MESSAGE);
            return(NULL);
        }
        break;
    case xmlSecKeyDataFormatPkcs8Der:
        /* try to read private key first */
        pKey = d2i_PKCS8PrivateKey_bio(bio, NULL,
                            XMLSEC_PTR_TO_FUNC(pem_password_cb, pwdCallback),
                            pwdCallbackCtx);
        if(pKey == NULL) {
            xmlSecError(XMLSEC_ERRORS_HERE,
                        NULL,
                        "d2i_PrivateKey_bio and d2i_PUBKEY_bio",
                        XMLSEC_ERRORS_R_CRYPTO_FAILED,
                        XMLSEC_ERRORS_NO_MESSAGE);
            return(NULL);
        }
        break;
#ifndef XMLSEC_NO_X509
    case xmlSecKeyDataFormatPkcs12:
        key = xmlSecOpenSSLAppPkcs12LoadBIO(bio, pwd, pwdCallback, pwdCallbackCtx);
        if(key == NULL) {
            xmlSecError(XMLSEC_ERRORS_HERE,
                        NULL,
                        "xmlSecOpenSSLAppPkcs12LoadBIO",
                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
                        XMLSEC_ERRORS_NO_MESSAGE);
            return(NULL);
        }
        return(key);

    case xmlSecKeyDataFormatCertPem:
    case xmlSecKeyDataFormatCertDer:
        key = xmlSecOpenSSLAppKeyFromCertLoadBIO(bio, format);
        if(key == NULL) {
            xmlSecError(XMLSEC_ERRORS_HERE,
                        NULL,
                        "xmlSecOpenSSLAppKeyFromCertLoadBIO",
                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
                        XMLSEC_ERRORS_NO_MESSAGE);
            return(NULL);
        }
        return(key);
#endif /* XMLSEC_NO_X509 */

    default:
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    NULL,
                    XMLSEC_ERRORS_R_INVALID_FORMAT,
                    "format=%d", format);
        return(NULL);
    }

    data = xmlSecOpenSSLEvpKeyAdopt(pKey);
    if(data == NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "xmlSecOpenSSLEvpKeyAdopt",
                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
                    XMLSEC_ERRORS_NO_MESSAGE);
        EVP_PKEY_free(pKey);
        return(NULL);
    }

    key = xmlSecKeyCreate();
    if(key == NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "xmlSecKeyCreate",
                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
                    XMLSEC_ERRORS_NO_MESSAGE);
        xmlSecKeyDataDestroy(data);
        return(NULL);
    }

    ret = xmlSecKeySetValue(key, data);
    if(ret < 0) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "xmlSecKeySetValue",
                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
                    "data=%s",
                    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)));
        xmlSecKeyDestroy(key);
        xmlSecKeyDataDestroy(data);
        return(NULL);
    }

    return(key);
}
예제 #12
0
static int openssl_pkey_read(lua_State*L)
{
  EVP_PKEY * key = NULL;
  BIO* in = load_bio_object(L, 1);
  int priv = lua_isnoneornil(L, 2) ? 0 : auxiliar_checkboolean(L, 2);
  int fmt = luaL_checkoption(L, 3, "auto", format);
  const char* passphrase = luaL_optstring(L, 4, NULL);
  int type = -1;
  if (passphrase)
  {
    if (strcmp(passphrase, "rsa") == 0 || strcmp(passphrase, "RSA") == 0)
      type = EVP_PKEY_RSA;
    else if (strcmp(passphrase, "dsa") == 0 || strcmp(passphrase, "DSA") == 0)
      type = EVP_PKEY_DSA;
    else if (strcmp(passphrase, "ec") == 0 || strcmp(passphrase, "EC") == 0)
      type = EVP_PKEY_EC;
  }

  if (fmt == FORMAT_AUTO)
  {
    fmt = bio_is_der(in) ? FORMAT_DER : FORMAT_PEM;
  }

  if (!priv)
  {
    if (fmt == FORMAT_PEM)
    {
      key = PEM_read_bio_PUBKEY(in, NULL, NULL, (void*)passphrase);
      BIO_reset(in);
      if (key == NULL && type == EVP_PKEY_RSA)
      {
        RSA* rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
        if (rsa)
        {
          key = EVP_PKEY_new();
          EVP_PKEY_assign_RSA(key, rsa);
        }
      }
    }else
    if (fmt == FORMAT_DER)
    {
      key = d2i_PUBKEY_bio(in, NULL);
      BIO_reset(in);
      if (!key && type!=-1)
      {
        char * bio_mem_ptr;
        long bio_mem_len;

        bio_mem_len = BIO_get_mem_data(in, &bio_mem_ptr);
        key = d2i_PublicKey(type, NULL, (const unsigned char **)&bio_mem_ptr, bio_mem_len);
        BIO_reset(in);
      }
    }
  }
  else
  {
    if (fmt == FORMAT_PEM)
    {
      key = PEM_read_bio_PrivateKey(in, NULL, NULL, (void*)passphrase);
      BIO_reset(in);
    }else
    if (fmt == FORMAT_DER)
    {
      if (passphrase)
        key = d2i_PKCS8PrivateKey_bio(in, NULL, NULL, (void*)passphrase);
      else
        key = d2i_PrivateKey_bio(in, NULL);
      BIO_reset(in);

      if (!key && type != -1)
      {
        char * bio_mem_ptr;
        long bio_mem_len;

        bio_mem_len = BIO_get_mem_data(in, &bio_mem_ptr);
        key = d2i_PrivateKey(type, NULL, (const unsigned char **)&bio_mem_ptr, bio_mem_len);
        BIO_reset(in);
      }
    }
  }
  BIO_free(in);
  if (key)
  {
    PUSH_OBJECT(key, "openssl.evp_pkey");
    return 1;
  }
  return openssl_pushresult(L, 0);
}
예제 #13
0
void RedChannelBase::link(uint32_t connection_id, const std::string& password,
                          int protocol)
{
    SpiceLinkHeader header;
    SpiceLinkMess link_mess;
    SpiceLinkReply* reply;
    uint32_t link_res;
    uint32_t i;

    EVP_PKEY *pubkey;
    int nRSASize;
    BIO *bioKey;
    RSA *rsa;
    uint8_t *buffer, *p;
    uint32_t expected_major;

    header.magic = SPICE_MAGIC;
    header.size = sizeof(link_mess);
    if (protocol == 1) {
        /* protocol 1 == major 1, old 0.4 protocol, last active minor */
        expected_major = header.major_version = 1;
        header.minor_version = 3;
    } else if (protocol == 2) {
        /* protocol 2 == current */
        expected_major = header.major_version = SPICE_VERSION_MAJOR;
        header.minor_version = SPICE_VERSION_MINOR;
    } else {
        THROW("unsupported protocol version specified");
    }
    link_mess.connection_id = connection_id;
    link_mess.channel_type = _type;
    link_mess.channel_id = _id;
    link_mess.num_common_caps = get_common_caps().size();
    link_mess.num_channel_caps = get_caps().size();
    link_mess.caps_offset = sizeof(link_mess);
    header.size += (link_mess.num_common_caps + link_mess.num_channel_caps) * sizeof(uint32_t);

    buffer =
        new uint8_t[sizeof(header) + sizeof(link_mess) +
                    _common_caps.size() * sizeof(uint32_t) +
                    _caps.size() * sizeof(uint32_t)];
    p = buffer;

    memcpy(p, (uint8_t*)&header, sizeof(header));
    p += sizeof(header);
    memcpy(p, (uint8_t*)&link_mess, sizeof(link_mess));
    p += sizeof(link_mess);
    for (i = 0; i < _common_caps.size(); i++) {
        *(uint32_t *)p = _common_caps[i];
        p += sizeof(uint32_t);
    }

    for (i = 0; i < _caps.size(); i++) {
        *(uint32_t *)p = _caps[i];
        p += sizeof(uint32_t);
    }

    send(buffer, p - buffer);
    delete [] buffer;

    recive((uint8_t*)&header, sizeof(header));

    if (header.magic != SPICE_MAGIC) {
        THROW_ERR(SPICEC_ERROR_CODE_CONNECT_FAILED, "bad magic");
    }

    if (header.major_version != expected_major) {
        THROW_ERR(SPICEC_ERROR_CODE_VERSION_MISMATCH,
                  "version mismatch: expect %u got %u",
                  expected_major,
                  header.major_version);
    }

    _remote_major = header.major_version;
    _remote_minor = header.minor_version;

    AutoArray<uint8_t> reply_buf(new uint8_t[header.size]);
    recive(reply_buf.get(), header.size);

    reply = (SpiceLinkReply *)reply_buf.get();

    if (reply->error != SPICE_LINK_ERR_OK) {
        THROW_ERR(SPICEC_ERROR_CODE_CONNECT_FAILED, "connect error %u - %s",
                        reply->error, spice_link_error_string(reply->error));
    }

    uint32_t num_caps = reply->num_channel_caps + reply->num_common_caps;
    if ((uint8_t *)(reply + 1) > reply_buf.get() + header.size ||
        (uint8_t *)reply + reply->caps_offset + num_caps * sizeof(uint32_t) >
                                                                    reply_buf.get() + header.size) {
        THROW_ERR(SPICEC_ERROR_CODE_CONNECT_FAILED, "access violation");
    }

    uint32_t *caps = (uint32_t *)((uint8_t *)reply + reply->caps_offset);

    _remote_common_caps.clear();
    for (i = 0; i < reply->num_common_caps; i++, caps++) {
        _remote_common_caps.resize(i + 1);
        _remote_common_caps[i] = *caps;
    }

    _remote_caps.clear();
    for (i = 0; i < reply->num_channel_caps; i++, caps++) {
        _remote_caps.resize(i + 1);
        _remote_caps[i] = *caps;
    }

    bioKey = BIO_new(BIO_s_mem());
    if (bioKey != NULL) {
        BIO_write(bioKey, reply->pub_key, SPICE_TICKET_PUBKEY_BYTES);
        pubkey = d2i_PUBKEY_bio(bioKey, NULL);
        rsa = pubkey->pkey.rsa;
        nRSASize = RSA_size(rsa);
        AutoArray<unsigned char> bufEncrypted(new unsigned char[nRSASize]);

        /*
                The use of RSA encryption limit the potential maximum password length.
                for RSA_PKCS1_OAEP_PADDING it is RSA_size(rsa) - 41.
        */
        if (RSA_public_encrypt(password.length() + 1, (unsigned char *)password.c_str(),
                               (uint8_t *)bufEncrypted.get(),
                               rsa, RSA_PKCS1_OAEP_PADDING) > 0) {
            send((uint8_t*)bufEncrypted.get(), nRSASize);
        } else {
            THROW("could not encrypt password");
        }

        memset(bufEncrypted.get(), 0, nRSASize);
    } else {
        THROW("Could not initiate BIO");
    }

    BIO_free(bioKey);

    recive((uint8_t*)&link_res, sizeof(link_res));
    if (link_res != SPICE_LINK_ERR_OK) {
        int error_code = (link_res == SPICE_LINK_ERR_PERMISSION_DENIED) ?
                                SPICEC_ERROR_CODE_CONNECT_FAILED : SPICEC_ERROR_CODE_CONNECT_FAILED;
        THROW_ERR(error_code, "connect failed %u", link_res);
    }
}
예제 #14
0
파일: csr.c 프로젝트: fiendish/lua-openssl
/***
sign x509_req object

@function sign
@tparam evp_pkey pkey private key which to sign x509_req object
@tparam number|string|evp_md md message digest alg used to sign
@treturn boolean result true for suceess
*/
static LUA_FUNCTION(openssl_csr_sign)
{
  X509_REQ * csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req");
  EVP_PKEY *pubkey = X509_REQ_get_pubkey(csr);
  if (auxiliar_getclassudata(L, "openssl.evp_pkey", 2))
  {
    EVP_PKEY *pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey");
    const EVP_MD* md = get_digest(L, 3, "sha256");
    int ret = 1;
    if (pubkey == NULL)
    {
      BIO* bio = BIO_new(BIO_s_mem());
      if ((ret = i2d_PUBKEY_bio(bio, pkey)) == 1)
      {
        pubkey = d2i_PUBKEY_bio(bio, NULL);
        if (pubkey)
        {
          ret = X509_REQ_set_pubkey(csr, pubkey);
          EVP_PKEY_free(pubkey);
        }
        else
        {
          ret = 0;
        }
      }
      BIO_free(bio);
    }
    else
    {
      EVP_PKEY_free(pubkey);
    }
    if (ret == 1)
      ret = X509_REQ_sign(csr, pkey, md);
    return openssl_pushresult(L, ret);
  }
  else if (lua_isstring(L, 2))
  {
    size_t siglen;
    unsigned char* sigdata = (unsigned char*)luaL_checklstring(L, 2, &siglen);
    const EVP_MD* md = get_digest(L, 3, NULL);
    ASN1_BIT_STRING *sig = NULL;
    X509_ALGOR *alg = NULL;

    luaL_argcheck(L, pubkey != NULL, 1, "has not set public key!!!");

    X509_REQ_get0_signature(csr, (const ASN1_BIT_STRING **)&sig, (const X509_ALGOR **)&alg);
    /* (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) ? V_ASN1_NULL : V_ASN1_UNDEF, */
    X509_ALGOR_set0((X509_ALGOR *)alg, OBJ_nid2obj(EVP_MD_pkey_type(md)), V_ASN1_NULL, NULL);

    ASN1_BIT_STRING_set((ASN1_BIT_STRING *)sig, sigdata, siglen);
    /*
    * In the interests of compatibility, I'll make sure that the bit string
    * has a 'not-used bits' value of 0
    */
    sig->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
    sig->flags |= ASN1_STRING_FLAG_BITS_LEFT;
    lua_pushboolean(L, 1);
    return 1;
  }
  else
  {
    int inl;
    unsigned char* tosign = NULL;
    luaL_argcheck(L, pubkey != NULL, 1, "has not set public key!!!");

    inl = i2d_re_X509_REQ_tbs(csr, &tosign);
    if (inl > 0 && tosign)
    {
      lua_pushlstring(L, (const char*)tosign, inl);
      OPENSSL_free(tosign);
      return 1;
    }
    return openssl_pushresult(L, 0);
  }
}