예제 #1
0
파일: hash.c 프로젝트: Aakanksha/c-twitter
int oauth_verify_rsa_sha1 (const char *m, const char *c, const char *s) {
  EVP_MD_CTX md_ctx;
  EVP_PKEY *pkey;
  BIO *in;
  X509 *cert = NULL;
  unsigned char *b64d;
  int slen, err;

  in = BIO_new_mem_buf((unsigned char*)c, strlen(c));
  cert = PEM_read_bio_X509(in, NULL, 0, NULL);
  if (cert)  {
    pkey = (EVP_PKEY *) X509_get_pubkey(cert); 
    X509_free(cert);
  } else {
    pkey = PEM_read_bio_PUBKEY(in, NULL, 0, NULL);
  }
  BIO_free(in);
  if (pkey == NULL) {
  //fprintf(stderr, "could not read cert/pubkey.\n");
    return -2;
  }

  b64d= (unsigned char*) xmalloc(sizeof(char)*strlen(s));
  slen = oauth_decode_base64(b64d, s);

  EVP_VerifyInit(&md_ctx, EVP_sha1());
  EVP_VerifyUpdate(&md_ctx, m, strlen(m));
  err = EVP_VerifyFinal(&md_ctx, b64d, slen, pkey);
  EVP_MD_CTX_cleanup(&md_ctx);
  EVP_PKEY_free(pkey);
  free(b64d);
  return (err);
}
예제 #2
0
static EVP_PKEY *load_pubkey(const char *file)
{
	BIO *key=NULL;
	EVP_PKEY *pkey=NULL;

	if (file == NULL)
	{
		ERROR("no keyfile specified");
		goto end;
	}

	key=BIO_new(BIO_s_file());
	if (key == NULL)
	{
		goto end;
	}

	if (BIO_read_filename(key, file) <= 0)
	{
		printf("Error opening %s \n", file);
		goto end;
	}

	pkey=PEM_read_bio_PUBKEY(key, NULL, NULL, NULL);
end:
	if (key != NULL) BIO_free(key);
	if (pkey == NULL)
		ERROR("unable to load key filename %s", file);
	return(pkey);
}
예제 #3
0
RSA* getRSA(unsigned char* unspubkey, int pubkeyLen) {
    BIO *pkey = NULL;
    EVP_PKEY *sigkey = NULL;
    RSA *rsa = NULL;

    pkey = BIO_new_mem_buf(unspubkey, pubkeyLen);
    if (!pkey) {
        goto end;
    }

    sigkey = PEM_read_bio_PUBKEY(pkey, NULL, NULL, NULL);
    if (!sigkey) {
        goto end;
    }

    rsa = EVP_PKEY_get1_RSA(sigkey);
    if (!rsa) {
        goto end;
    }

end:

    if (pkey) BIO_free (pkey);
    if (sigkey) EVP_PKEY_free(sigkey);
    return rsa;
}
예제 #4
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);
}
예제 #5
0
파일: crypto.c 프로젝트: 99Frankie/chaosvpn
EVP_PKEY *
crypto_load_key(const char *key, const bool is_private)
{
	BIO *bio;
	EVP_PKEY *pkey;

	bio = BIO_new_mem_buf((void *)key, strlen(key));
	if (bio == NULL) {
            log_err("crypto_load_key: BIO_new_mem_buf() failed\n");
	    return NULL;
	}

        /* read and parse key */
        if (is_private) {
            pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
        } else {
            pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
        }
        BIO_free(bio);
        if (pkey == NULL) {
            log_err("crypto_load_key: loading and parsing key failed\n");
            ERR_print_errors_fp(stderr);
            return NULL;
        }
        
        return pkey;
}
예제 #6
0
// From keygen_test.cpp
EVP_PKEY* readPublicKey( const char* rawBuffer ){
    EVP_PKEY* evpKey = nullptr;
    BIO* buff = BIO_new_mem_buf( (void*)rawBuffer, std::strlen( rawBuffer ) );
    PEM_read_bio_PUBKEY( buff, &evpKey, nullptr, nullptr );
    BIO_free( buff );
    return evpKey;
}
예제 #7
0
int RSAZCryptor::setPublicKey(const char* publickey)
{
    if(!publickey || !*publickey)
    {
        if(m_trace_level > 0)
            printf("Warning: publickey is empty\n");

        return -1;
    }

    if(m_trace_level > 10)
        printf("setting publickey:\n%s\n", publickey);

    if(pubkey)
    {
        EVP_PKEY_free(pubkey);
        pubkey = NULL;
    }

    if(pub_mem)
    {
        BIO_free(pub_mem);
        pub_mem = NULL;
    }

    if(pub_rsa)
    {
        RSA_free(pub_rsa);
        pub_rsa = NULL;
    }

    pub_size = 0;

    pub_mem = BIO_new(BIO_s_mem());
    BIO_puts(pub_mem, publickey);
    if (!(pubkey = PEM_read_bio_PUBKEY(pub_mem, NULL, NULL, NULL)))
    {
        throw_error();
    }

    if(!(pub_rsa = EVP_PKEY_get1_RSA(pubkey)))
    {
        throw_error();
    }

    pub_size = RSA_size(pub_rsa);       

    generate_key(32, m_sessionkey);
    ZBuffer ekeybuf;
    publickey_encrypt(m_sessionkey.length(), m_sessionkey.buffer(), ekeybuf);
    base64_encode(ekeybuf.length(), ekeybuf.buffer(), m_encrypted_sessionkey);

    return 0;
}
// Low-level
//
// (Internal) ASCII-Armored key ====> (Internal) Actual loaded OpenSSL key.
//
//
EVP_PKEY * OTAsymmetricKey_OpenSSL::OTAsymmetricKey_OpenSSLPrivdp::InstantiatePublicKey(OTPasswordData * pPWData/*=NULL*/)
{
    OT_ASSERT(m_pKey     == NULL);
    OT_ASSERT(backlink->m_p_ascKey != NULL);
    OT_ASSERT(backlink->IsPublic());
    
    const char * szFunc = "OTAsymmetricKey_OpenSSL::InstantiatePublicKey";
    // ------------------------------
    EVP_PKEY * pReturnKey = NULL;
    OTPayload  theData;
    // -----------------------------------------------
    // This base64 decodes the string m_p_ascKey into the
    // binary payload object "theData"
    //
    backlink->m_p_ascKey->GetData(theData);
    
    if (theData.GetSize() > 0)
    {
        // -------------------------------------------
        // Next, copy theData's contents into a new BIO_mem_buf,
        // so OpenSSL can load the key out of it.
        //
        OpenSSL_BIO keyBio	= BIO_new_mem_buf(static_cast<char*>(const_cast<void*>(theData.GetPayloadPointer())), 
                                      theData.GetSize());
        OT_ASSERT_MSG(NULL != keyBio, "OTAsymmetricKey_OpenSSL::InstantiatePublicKey: Assert: NULL != keyBio \n");
        // -------------------------------------------
        // Next we load up the key from the BIO string into an instantiated key object.
        //
        OTPasswordData thePWData("OTAsymmetricKey_OpenSSL::InstantiatePublicKey is calling PEM_read_bio_PUBKEY...");
        
        if (NULL == pPWData)
            pPWData = &thePWData;
        
        pReturnKey = PEM_read_bio_PUBKEY(keyBio, NULL, OTAsymmetricKey::GetPasswordCallback(), pPWData);
        // -------------------------------------------

        // -------------------------------------------
        backlink->ReleaseKeyLowLevel(); // Release whatever loaded key I might have already had.
        
        if (NULL != pReturnKey)
        {
            m_pKey = pReturnKey;
            OTLog::vOutput(4, "%s: Success reading public key from ASCII-armored data:\n\n%s\n\n",
                           szFunc, backlink->m_p_ascKey->Get());
            return m_pKey;
        }
    }
    
    OTLog::vError("%s: Failed reading public key from ASCII-armored data:\n\n%s\n\n", 
                  szFunc, backlink->m_p_ascKey->Get());
    return NULL;
}
예제 #9
0
파일: mcssl.cpp 프로젝트: bduck/livecode
bool load_pem_key(const char *p_data, uint32_t p_length, RSA_KEYTYPE p_type, const char *p_passphrase, EVP_PKEY *&r_key)
{
	bool t_success = true;
	BIO *t_data = NULL;
	EVP_PKEY *t_key = NULL;
	t_data = BIO_new_mem_buf((void*)p_data, p_length);
	t_success = t_data != NULL;
	char t_empty_pass[] = "";
	char *t_passphrase = (p_passphrase != NULL) ? (char*)p_passphrase : t_empty_pass;

	if (t_success)
	{
		switch (p_type)
		{
		case RSAKEY_PUBKEY:
			t_key = PEM_read_bio_PUBKEY(t_data, NULL, NULL, t_passphrase);
			t_success = (t_key != NULL);
			break;
		case RSAKEY_PRIVKEY:
			t_key = PEM_read_bio_PrivateKey(t_data, NULL, NULL, t_passphrase);
			t_success = (t_key != NULL);
			break;
		case RSAKEY_CERT:
			{
				X509* t_cert = NULL;
				t_cert = PEM_read_bio_X509_AUX(t_data, NULL, NULL, t_passphrase);
				t_success = (t_cert != NULL);
				if (t_success)
				{
					t_key = X509_get_pubkey(t_cert);
					t_success = (t_key != NULL);
					X509_free(t_cert);
				}
			}
			break;
		default:
			// error: unknown key type
			t_success = false;
		}
	}

	if (t_data != NULL)
		BIO_free(t_data);
	if (t_success)
		r_key = t_key;

	return t_success;
}
예제 #10
0
파일: key_utils.c 프로젝트: cawka/PyNDN
int
put_key_pem(int is_public_only, PyObject *py_key_pem,
            PyObject **py_private_key_ndn, PyObject **py_public_key_ndn,
            PyObject **py_public_key_digest,
            char *password)
{
	unsigned char *key_pem;
	Py_ssize_t pem_len;
	struct ndn_pkey *key = NULL;
	BIO *bio = NULL;
	int r;
	unsigned long err;

	r = PyBytes_AsStringAndSize(py_key_pem, (char **) &key_pem, &pem_len);
	JUMP_IF_NEG(r, error);

	bio = BIO_new_mem_buf(key_pem, pem_len);
	JUMP_IF_NULL(bio, openssl_error);

	if (is_public_only)
          key = (struct ndn_pkey*)PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
	else
          key = (struct ndn_pkey*)PEM_read_bio_PrivateKey(bio, NULL, NULL, password);
	JUMP_IF_NULL(key, openssl_error);

	r = ndn_keypair(is_public_only, key, py_private_key_ndn, py_public_key_ndn);
	JUMP_IF_NEG(r, error);

	r = create_public_key_digest(key, py_public_key_digest, NULL);
	JUMP_IF_NEG(r, error);

	return 0;

openssl_error:
	err = ERR_get_error();
	PyErr_Format(g_PyExc_NDNKeyError, "Unable to parse key: %s",
			ERR_reason_error_string(err));
error:
	EVP_PKEY_free ((EVP_PKEY *)key);
	BIO_free(bio);
	return -1;
}
RSA* key_from_bio(BIO *key_bio, BOOL is_private) {

  EVP_PKEY *pkey = NULL;
  
  if(is_private) {
    pkey = PEM_read_bio_PrivateKey(key_bio, 
                          NULL,NULL, NULL);
  }else {
    pkey = PEM_read_bio_PUBKEY(key_bio, NULL,
                                        NULL, NULL);
  }
  if(!pkey) {
      fprintf(stderr, "ERROR: key read from BIO is null\n");
      exit(1);
  }
  BIO_free(key_bio);
  RSA *rsa = EVP_PKEY_get1_RSA(pkey);
  EVP_PKEY_free(pkey);
  return rsa;
}
예제 #12
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;
}
예제 #13
0
PublicKey::PublicKey(std::string &pemEncoded)
		throw (EncodeException) : AsymmetricKey(NULL)
{
	BIO *buffer;
	buffer = BIO_new(BIO_s_mem());
	if (buffer == NULL)
	{
		throw EncodeException(EncodeException::BUFFER_CREATING, "PublicKey::PublicKey");
	}
	if ((unsigned int)(BIO_write(buffer, pemEncoded.c_str(), pemEncoded.size())) != pemEncoded.size())
	{
		BIO_free(buffer);
		throw EncodeException(EncodeException::BUFFER_WRITING, "PublicKey::PublicKey");
	}
	this->key = PEM_read_bio_PUBKEY(buffer, NULL, NULL, NULL);
	if (this->key == NULL)
	{
		BIO_free(buffer);
		throw EncodeException(EncodeException::PEM_DECODE, "PublicKey::PublicKey");
	}
	BIO_free(buffer);
}
예제 #14
0
파일: pki_evp.cpp 프로젝트: J-Javan/xca
void pki_evp::fromPEM_BIO(BIO *bio, QString name)
{
	EVP_PKEY *pkey;
	int pos;
	pass_info p(XCA_TITLE, QObject::tr(
			"Please enter the password to decrypt the private key."));
	pos = BIO_tell(bio);
	pkey = PEM_read_bio_PrivateKey(bio, NULL, MainWindow::passRead, &p);
	if (!pkey){
		pki_ign_openssl_error();
		pos = BIO_seek(bio, pos);
		pkey = PEM_read_bio_PUBKEY(bio, NULL, MainWindow::passRead, &p);
	}
	if (pkey){
		if (key)
			EVP_PKEY_free(key);
		key = pkey;
		if (EVP_PKEY_isPrivKey(key))
			bogusEncryptKey();
		setIntName(rmslashdot(name));
	}
	openssl_error(name);
}
int MAIN(int argc, char **argv)
	{
	unsigned char *buf=NULL;
	int i,err=0;
	const EVP_MD *md=NULL,*m;
	BIO *in=NULL,*inp;
	BIO *bmd=NULL;
	BIO *out = NULL;
	const char *name;
#define PROG_NAME_SIZE  39
	char pname[PROG_NAME_SIZE+1];
	int separator=0;
	int debug=0;
	const char *outfile = NULL, *keyfile = NULL;
	const char *sigfile = NULL, *randfile = NULL;
	int out_bin = -1, want_pub = 0, do_verify = 0;
	EVP_PKEY *sigkey = NULL;
	unsigned char *sigbuf = NULL;
	int siglen = 0;

	apps_startup();

	if ((buf=(unsigned char *)OPENSSL_malloc(BUFSIZE)) == NULL)
		{
		BIO_printf(bio_err,"out of memory\n");
		goto end;
		}
	if (bio_err == NULL)
		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);

	/* first check the program name */
	program_name(argv[0],pname,PROG_NAME_SIZE);

	md=EVP_get_digestbyname(pname);

	argc--;
	argv++;
	while (argc > 0)
		{
		if ((*argv)[0] != '-') break;
		if (strcmp(*argv,"-c") == 0)
			separator=1;
		else if (strcmp(*argv,"-rand") == 0)
			{
			if (--argc < 1) break;
			randfile=*(++argv);
			}
		else if (strcmp(*argv,"-out") == 0)
			{
			if (--argc < 1) break;
			outfile=*(++argv);
			}
		else if (strcmp(*argv,"-sign") == 0)
			{
			if (--argc < 1) break;
			keyfile=*(++argv);
			}
		else if (strcmp(*argv,"-verify") == 0)
			{
			if (--argc < 1) break;
			keyfile=*(++argv);
			want_pub = 1;
			do_verify = 1;
			}
		else if (strcmp(*argv,"-prverify") == 0)
			{
			if (--argc < 1) break;
			keyfile=*(++argv);
			do_verify = 1;
			}
		else if (strcmp(*argv,"-signature") == 0)
			{
			if (--argc < 1) break;
			sigfile=*(++argv);
			}
		else if (strcmp(*argv,"-hex") == 0)
			out_bin = 0;
		else if (strcmp(*argv,"-binary") == 0)
			out_bin = 1;
		else if (strcmp(*argv,"-d") == 0)
			debug=1;
		else if ((m=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
			md=m;
		else
			break;
		argc--;
		argv++;
		}

	if (md == NULL)
		md=EVP_md5();

	if(do_verify && !sigfile) {
		BIO_printf(bio_err, "No signature to verify: use the -signature option\n");
		err = 1; 
		goto end;
	}

	if ((argc > 0) && (argv[0][0] == '-')) /* bad option */
		{
		BIO_printf(bio_err,"unknown option '%s'\n",*argv);
		BIO_printf(bio_err,"options are\n");
		BIO_printf(bio_err,"-c              to output the digest with separating colons\n");
		BIO_printf(bio_err,"-d              to output debug info\n");
		BIO_printf(bio_err,"-hex            output as hex dump\n");
		BIO_printf(bio_err,"-binary         output in binary form\n");
		BIO_printf(bio_err,"-sign   file    sign digest using private key in file\n");
		BIO_printf(bio_err,"-verify file    verify a signature using public key in file\n");
		BIO_printf(bio_err,"-prverify file  verify a signature using private key in file\n");
		BIO_printf(bio_err,"-signature file signature to verify\n");
		BIO_printf(bio_err,"-binary         output in binary form\n");

		BIO_printf(bio_err,"-%3s to use the %s message digest algorithm (default)\n",
			LN_md5,LN_md5);
		BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
			LN_md4,LN_md4);
		BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
			LN_md2,LN_md2);
		BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
			LN_sha1,LN_sha1);
		BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
			LN_sha,LN_sha);
		BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
			LN_mdc2,LN_mdc2);
		BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
			LN_ripemd160,LN_ripemd160);
		err=1;
		goto end;
		}

	in=BIO_new(BIO_s_file());
	bmd=BIO_new(BIO_f_md());
	if (debug)
		{
		BIO_set_callback(in,BIO_debug_callback);
		/* needed for windows 3.1 */
		BIO_set_callback_arg(in,bio_err);
		}

	if ((in == NULL) || (bmd == NULL))
		{
		ERR_print_errors(bio_err);
		goto end;
		}

	if(out_bin == -1) {
		if(keyfile) out_bin = 1;
		else out_bin = 0;
	}

	if(randfile)
		app_RAND_load_file(randfile, bio_err, 0);

	if(outfile) {
		if(out_bin)
			out = BIO_new_file(outfile, "wb");
		else    out = BIO_new_file(outfile, "w");
	} else {
		out = BIO_new_fp(stdout, BIO_NOCLOSE);
#ifdef VMS
		{
		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
		out = BIO_push(tmpbio, out);
		}
#endif
	}

	if(!out) {
		BIO_printf(bio_err, "Error opening output file %s\n", 
					outfile ? outfile : "(stdout)");
		ERR_print_errors(bio_err);
		goto end;
	}

	if(keyfile) {
		BIO *keybio;
		keybio = BIO_new_file(keyfile, "r");
		if(!keybio) {
			BIO_printf(bio_err, "Error opening key file %s\n",
								keyfile);
			ERR_print_errors(bio_err);
			goto end;
		}
		
		if(want_pub) 
			sigkey = PEM_read_bio_PUBKEY(keybio, NULL, NULL, NULL);
		else sigkey = PEM_read_bio_PrivateKey(keybio, NULL, NULL, NULL);
		BIO_free(keybio);
		if(!sigkey) {
			BIO_printf(bio_err, "Error reading key file %s\n",
								keyfile);
			ERR_print_errors(bio_err);
			goto end;
		}
	}

	if(sigfile && sigkey) {
		BIO *sigbio;
		sigbio = BIO_new_file(sigfile, "rb");
		siglen = EVP_PKEY_size(sigkey);
		sigbuf = OPENSSL_malloc(siglen);
		if(!sigbio) {
			BIO_printf(bio_err, "Error opening signature file %s\n",
								sigfile);
			ERR_print_errors(bio_err);
			goto end;
		}
		siglen = BIO_read(sigbio, sigbuf, siglen);
		BIO_free(sigbio);
		if(siglen <= 0) {
			BIO_printf(bio_err, "Error reading signature file %s\n",
								sigfile);
			ERR_print_errors(bio_err);
			goto end;
		}
	}
		


	/* we use md as a filter, reading from 'in' */
	BIO_set_md(bmd,md);
	inp=BIO_push(bmd,in);

	if (argc == 0)
		{
		BIO_set_fp(in,stdin,BIO_NOCLOSE);
		do_fp(out, buf,inp,separator, out_bin, sigkey, sigbuf, siglen);
		}
	else
		{
		name=OBJ_nid2sn(md->type);
		for (i=0; i<argc; i++)
			{
			if (BIO_read_filename(in,argv[i]) <= 0)
				{
				perror(argv[i]);
				err++;
				continue;
				}
			if(!out_bin) BIO_printf(out, "%s(%s)= ",name,argv[i]);
			do_fp(out, buf,inp,separator, out_bin, sigkey, 
								sigbuf, siglen);
			(void)BIO_reset(bmd);
			}
		}
end:
	if (buf != NULL)
		{
		memset(buf,0,BUFSIZE);
		OPENSSL_free(buf);
		}
	if (in != NULL) BIO_free(in);
	BIO_free_all(out);
	EVP_PKEY_free(sigkey);
	if(sigbuf) OPENSSL_free(sigbuf);
	if (bmd != NULL) BIO_free(bmd);
	EXIT(err);
	}
예제 #16
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);
}
//static      // CALLER must EVP_pkey_free!
EVP_PKEY * OTAsymmetricKey_OpenSSL::OTAsymmetricKey_OpenSSLPrivdp::CopyPublicKey(EVP_PKEY & theKey, OTPasswordData * pPWData/*=NULL*/, OTPassword * pImportPassword/*=NULL*/)
{
    // ----------------------------------------
	// Create a new memory buffer on the OpenSSL side
	OpenSSL_BIO bmem = BIO_new(BIO_s_mem());
	OT_ASSERT_MSG(NULL != bmem, "OTAsymmetricKey_OpenSSL::CopyPublicKey: ASSERT: NULL != bmem");
    
    EVP_PKEY * pReturnKey = NULL;
	// ----------------------------------------
	// write a public key to that buffer, from theKey (parameter.)
    //
	int32_t nWriteBio = PEM_write_bio_PUBKEY(bmem, &theKey);
	
	if (0 == nWriteBio)
	{
		OTLog::vError("%s: Error: Failed writing EVP_PKEY to memory buffer.\n", __FUNCTION__);
	}
	else 
	{
		OTLog::vOutput(5, "%s: Success writing EVP_PKEY to memory buffer.\n", __FUNCTION__);
		
		char * pChar = NULL;
		
		// After the below call, pChar will point to the memory buffer where the public key
        // supposedly is, and lSize will contain the size of that memory.
        //
		const int64_t      lSize = BIO_get_mem_data(bmem, &pChar);
        const uint32_t  nSize = static_cast<uint32_t>(lSize);
        
        if (nSize > 0)
        {
            OTPayload theData;

            // Set the buffer size in our own memory.
            theData.SetPayloadSize(nSize);
            
            void * pv = 
               OTPassword::safe_memcpy((static_cast<char*>(const_cast<void*>(theData.GetPayloadPointer()))), // destination
                                    theData.GetSize(),    // size of destination buffer.
                                    pChar,                // source
                                    nSize);               // length of source.
            // bool bZeroSource=false); // if true, sets the source buffer to zero after copying is done.

            if (NULL != pv)
            {
                // -----------------------------------------------
                // Next, copy theData's contents into a new BIO_mem_buf,
                // so OpenSSL can load the key out of it.
                //
                OpenSSL_BIO keyBio	= BIO_new_mem_buf(static_cast<char*>(const_cast<void*>(theData.GetPayloadPointer())), 
                                              theData.GetSize());
                OT_ASSERT_MSG(NULL != keyBio, "OTAsymmetricKey_OpenSSL::CopyPublicKey: Assert: NULL != keyBio \n");
                // -------------------------------------------
                // Next we load up the key from the BIO string into an instantiated key object.
                //
                OTPasswordData thePWData(NULL == pImportPassword ?
                                         "Enter your wallet master passphrase. (OTAsymmetricKey_OpenSSL::CopyPublicKey is calling PEM_read_bio_PUBKEY...)" :
                                         "Enter the passphrase for your exported Nym.");
                
                if (NULL == pImportPassword)
                    pReturnKey = PEM_read_bio_PUBKEY(keyBio, NULL, OTAsymmetricKey::GetPasswordCallback(), NULL == pPWData ? &thePWData : pPWData);
                else
                    pReturnKey = PEM_read_bio_PUBKEY(keyBio, NULL, 0, pImportPassword);
                // -------------------------------------------
                // We don't need the BIO anymore.
                // Free the BIO and related buffers, filters, etc. (auto with scope).
                //
            }
            else 
                OTLog::vError("%s: Error: Failed copying memory from BIO into OTPayload.\n");
            // -------------------------------------------            
        }
        else 
		{
			OTLog::vError("%s: Failed copying private key into memory.\n", __FUNCTION__);
		}
    }

    return pReturnKey;
}
예제 #18
0
static ERL_NIF_TERM x509_make_cert_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
  int expiry, serial;
  ASN1_INTEGER *asn1serial = NULL;
  BIGNUM *bn_rsa_genkey=NULL;
  BIO *bio_signing_private=NULL, *bio_issuer_cert = NULL, *bio_newcert_public = NULL;
  BIO *bio_x509=NULL;
  char *issuer_cert_pem=NULL;
  X509 *pX509 = NULL;
  X509 *pIssuerX509 = NULL;
  X509_NAME *pX509Name = NULL;
  X509_NAME *pIssuerName = NULL;
  x509_subject_entry *subject_entries;
  int num_subject_entries;
  int iret = 0;
  RSA *rsa=NULL;
  unsigned long f4=RSA_F4;
  unsigned args_len=-1;
  char *signing_keys[2], *cert_keys[2];
  ERL_NIF_TERM tail, *arg_terms=NULL;
  int idx;
  ERL_NIF_TERM ret, x509term;
  int x509len;
  unsigned char *x509data;

  EVP_PKEY *evp_signing_private = EVP_PKEY_new();
  EVP_PKEY *evp_newcert_public_key = EVP_PKEY_new();
  /* set RSA key gen type */
  bn_rsa_genkey = BN_new();
  BN_set_word(bn_rsa_genkey, f4);

  //
  // 1. stick subject of CA cert into NewCert
  // 2. stick public key of NewKeypair into NewCert
  // 3. sign NewCert with CA keypair

  /* Should be 6 elements in the list of X509 parameters.  We'll check each */
  if(!enif_get_list_length(env, argv[0], &args_len) || args_len != 6 ||
     NULL == (arg_terms = (ERL_NIF_TERM*)malloc(args_len * sizeof(ERL_NIF_TERM)))) return enif_make_badarg(env);
  
  enif_get_list_cell(env, argv[0], &arg_terms[0], &tail);
  for(idx=1; idx<args_len; idx++){
    if(!enif_get_list_cell(env, tail, &arg_terms[idx], &tail)){
      free(arg_terms);
      return enif_make_badarg(env);
    }
  }
  
  idx=0;
  /* get the signing private key */
  x509_parse_keypair(env, "signing_key", arg_terms[idx++], signing_keys);

  /* get the issuer cert */
  x509_parse_issuer_cert(env, arg_terms[idx++], &issuer_cert_pem);

  /* get the soon-to-be cert's public key */
  x509_parse_keypair(env, "newcert_public_key", arg_terms[idx++], cert_keys);

  /* get the subject */
  x509_parse_subject(env, arg_terms[idx++], &num_subject_entries, &subject_entries);

  /* get the serial number */
  x509_parse_int_tuple(env, arg_terms[idx++], "serial", &serial);

  /* get the expiry */
  x509_parse_int_tuple(env, arg_terms[idx++], "expiry", &expiry);

  /* work the OpenSSL cert creation magic */
  if ((bio_signing_private = BIO_new_mem_buf(signing_keys[1], -1))
      && (rsa = PEM_read_bio_RSAPrivateKey(bio_signing_private, NULL, NULL, NULL))
      && (iret = EVP_PKEY_assign_RSA(evp_signing_private, rsa))
              
      && (bio_newcert_public = BIO_new_mem_buf(cert_keys[0], -1))
      && (evp_newcert_public_key = PEM_read_bio_PUBKEY(bio_newcert_public, NULL, NULL, NULL))
              
      && (bio_issuer_cert = BIO_new_mem_buf(issuer_cert_pem, -1))
      && (pIssuerX509 = PEM_read_bio_X509(bio_issuer_cert, NULL, NULL, NULL))
      && (pX509 = X509_new())) {
    /* if we've managed to generate a key and allocate structure memory,
       set X509 fields */
    asn1serial = ASN1_INTEGER_new();
    X509_set_version(pX509, 2); /* cert_helper uses '3' here */
    ASN1_INTEGER_set(asn1serial, serial);
    X509_set_serialNumber(pX509, asn1serial);
    X509_gmtime_adj(X509_get_notBefore(pX509),0);
    X509_gmtime_adj(X509_get_notAfter(pX509),(long)60*60*24*expiry);
    X509_set_pubkey(pX509, evp_newcert_public_key);
    pX509Name = X509_get_subject_name(pX509);
    
    while(--num_subject_entries >= 0){
      X509_NAME_add_entry_by_txt(pX509Name, (subject_entries[num_subject_entries]).name,
                                 MBSTRING_ASC, (unsigned char*)(subject_entries[num_subject_entries]).value, -1, -1, 0);
    }
    
    pIssuerName = X509_get_issuer_name(pIssuerX509);
    X509_set_issuer_name(pX509, pIssuerName);
    X509_sign(pX509, evp_signing_private, digest);
    
    bio_x509 = BIO_new(BIO_s_mem());
    PEM_write_bio_X509(bio_x509, pX509);
    
    x509len = BIO_get_mem_data(bio_x509, &x509data);
    memcpy(enif_make_new_binary(env, x509len, &x509term), x509data, x509len);
    ret = enif_make_tuple2(env, atom_x509_cert, x509term);
  }
    
 done:
  if(arg_terms) free(arg_terms);
  free_keys(signing_keys);
  free_keys(cert_keys);
  free_subject_entries(num_subject_entries, subject_entries);
  if(pX509) X509_free(pX509);
  if(pIssuerX509) X509_free(pIssuerX509);
  if(issuer_cert_pem) free(issuer_cert_pem);
  if(bio_issuer_cert) { BIO_set_close(bio_issuer_cert, BIO_NOCLOSE); BIO_free_all(bio_issuer_cert); }
  if(bio_signing_private) { BIO_set_close(bio_signing_private, BIO_NOCLOSE); BIO_free_all(bio_signing_private); }
  if(bio_newcert_public) { BIO_set_close(bio_newcert_public, BIO_NOCLOSE); BIO_free_all(bio_newcert_public); }
  if(bio_x509) BIO_free_all(bio_x509);
  if(asn1serial) ASN1_INTEGER_free(asn1serial);
  if(bn_rsa_genkey) BN_free(bn_rsa_genkey);
  if(rsa) RSA_free(rsa);

  return ret;
}
예제 #19
0
static int test_EVP_SM2_verify(void)
{
    /* From https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02#appendix-A */
    const char *pubkey =
       "-----BEGIN PUBLIC KEY-----\n"
       "MIIBMzCB7AYHKoZIzj0CATCB4AIBATAsBgcqhkjOPQEBAiEAhULWnkwETxjouSQ1\n"
       "v2/33kVyg5FcRVF9ci7biwjx38MwRAQgeHlotPoyw/0kF4Quc7v+/y88hItoMdfg\n"
       "7GUiizk35JgEIGPkxtOyOwyEnPhCQUhL/kj2HVmlsWugbm4S0donxSSaBEEEQh3r\n"
       "1hti6rZ0ZDTrw8wxXjIiCzut1QvcTE5sFH/t1D0GgFEry7QsB9RzSdIVO3DE5df9\n"
       "/L+jbqGoWEG55G4JogIhAIVC1p5MBE8Y6LkkNb9v990pdyBjBIVijVrnTufDLnm3\n"
       "AgEBA0IABArkx3mKoPEZRxvuEYJb5GICu3nipYRElel8BP9N8lSKfAJA+I8c1OFj\n"
       "Uqc8F7fxbwc1PlOhdtaEqf4Ma7eY6Fc=\n"
       "-----END PUBLIC KEY-----\n";

    const char *msg = "message digest";
    const char *id = "*****@*****.**";

    const uint8_t signature[] = {
       0x30, 0x44, 0x02, 0x20,

       0x40, 0xF1, 0xEC, 0x59, 0xF7, 0x93, 0xD9, 0xF4, 0x9E, 0x09, 0xDC,
       0xEF, 0x49, 0x13, 0x0D, 0x41, 0x94, 0xF7, 0x9F, 0xB1, 0xEE, 0xD2,
       0xCA, 0xA5, 0x5B, 0xAC, 0xDB, 0x49, 0xC4, 0xE7, 0x55, 0xD1,

       0x02, 0x20,

       0x6F, 0xC6, 0xDA, 0xC3, 0x2C, 0x5D, 0x5C, 0xF1, 0x0C, 0x77, 0xDF,
       0xB2, 0x0F, 0x7C, 0x2E, 0xB6, 0x67, 0xA4, 0x57, 0x87, 0x2F, 0xB0,
       0x9E, 0xC5, 0x63, 0x27, 0xA6, 0x7E, 0xC7, 0xDE, 0xEB, 0xE7
    };

    int rc = 0;
    BIO *bio = NULL;
    EVP_PKEY *pkey = NULL;
    EVP_MD_CTX *mctx = NULL;
    EVP_PKEY_CTX *pctx = NULL;

    bio = BIO_new_mem_buf(pubkey, strlen(pubkey));
    if (!TEST_true(bio != NULL))
        goto done;

    pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
    if (!TEST_true(pkey != NULL))
        goto done;

    if (!TEST_true(EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)))
        goto done;

    if (!TEST_ptr(mctx = EVP_MD_CTX_new()))
        goto done;

    if (!TEST_ptr(pctx = EVP_PKEY_CTX_new(pkey, NULL)))
        goto done;

    if (!TEST_int_gt(EVP_PKEY_CTX_set1_id(pctx, (const uint8_t *)id,
                                          strlen(id)), 0))
        goto done;

    EVP_MD_CTX_set_pkey_ctx(mctx, pctx);

    if (!TEST_true(EVP_DigestVerifyInit(mctx, NULL, EVP_sm3(), NULL, pkey)))
        goto done;

    if (!TEST_true(EVP_DigestVerifyUpdate(mctx, msg, strlen(msg))))
        goto done;

    if (!TEST_true(EVP_DigestVerifyFinal(mctx, signature, sizeof(signature))))
        goto done;
    rc = 1;

 done:
    BIO_free(bio);
    EVP_PKEY_free(pkey);
    EVP_PKEY_CTX_free(pctx);
    EVP_MD_CTX_free(mctx);
    return rc;
}
예제 #20
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);
}
예제 #21
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);
}
예제 #22
0
파일: jwt-openssl.c 프로젝트: asm128/libjwt
int jwt_verify_sha_pem(jwt_t *jwt, const char *head, const char *sig_b64)
{
	unsigned char *sig = NULL;
	EVP_MD_CTX *mdctx = NULL;
	ECDSA_SIG *ec_sig = NULL;
	BIGNUM *ec_sig_r = NULL;
	BIGNUM *ec_sig_s = NULL;
	EVP_PKEY *pkey = NULL;
	const EVP_MD *alg;
	int type;
	int pkey_type;
	BIO *bufkey = NULL;
	int ret = 0;
	int slen;

	switch (jwt->alg) {
	/* RSA */
	case JWT_ALG_RS256:
		alg = EVP_sha256();
		type = EVP_PKEY_RSA;
		break;
	case JWT_ALG_RS384:
		alg = EVP_sha384();
		type = EVP_PKEY_RSA;
		break;
	case JWT_ALG_RS512:
		alg = EVP_sha512();
		type = EVP_PKEY_RSA;
		break;

	/* ECC */
	case JWT_ALG_ES256:
		alg = EVP_sha256();
		type = EVP_PKEY_EC;
		break;
	case JWT_ALG_ES384:
		alg = EVP_sha384();
		type = EVP_PKEY_EC;
		break;
	case JWT_ALG_ES512:
		alg = EVP_sha512();
		type = EVP_PKEY_EC;
		break;

	default:
		return EINVAL;
	}

	sig = jwt_b64_decode(sig_b64, &slen);
	if (sig == NULL)
		VERIFY_ERROR(EINVAL);

	bufkey = BIO_new_mem_buf(jwt->key, jwt->key_len);
	if (bufkey == NULL)
		VERIFY_ERROR(ENOMEM);

	/* This uses OpenSSL's default passphrase callback if needed. The
	 * library caller can override this in many ways, all of which are
	 * outside of the scope of LibJWT and this is documented in jwt.h. */
	pkey = PEM_read_bio_PUBKEY(bufkey, NULL, NULL, NULL);
	if (pkey == NULL)
		VERIFY_ERROR(EINVAL);

	pkey_type = EVP_PKEY_id(pkey);
	if (pkey_type != type)
		VERIFY_ERROR(EINVAL);

	/* Convert EC sigs back to ASN1. */
	if (pkey_type == EVP_PKEY_EC) {
		unsigned int degree, bn_len;
		unsigned char *p;
		EC_KEY *ec_key;

		ec_sig = ECDSA_SIG_new();
		if (ec_sig == NULL)
			VERIFY_ERROR(ENOMEM);

		/* Get the actual ec_key */
		ec_key = EVP_PKEY_get1_EC_KEY(pkey);
		if (ec_key == NULL)
			VERIFY_ERROR(ENOMEM);

		degree = EC_GROUP_get_degree(EC_KEY_get0_group(ec_key));

		EC_KEY_free(ec_key);

		bn_len = (degree + 7) / 8;
		if ((bn_len * 2) != slen)
			VERIFY_ERROR(EINVAL);

		ec_sig_r = BN_bin2bn(sig, bn_len, NULL);
		ec_sig_s = BN_bin2bn(sig + bn_len, bn_len, NULL);
		if (ec_sig_r  == NULL || ec_sig_s == NULL)
			VERIFY_ERROR(EINVAL);

		ECDSA_SIG_set0(ec_sig, ec_sig_r, ec_sig_s);
		free(sig);

		slen = i2d_ECDSA_SIG(ec_sig, NULL);
		sig = malloc(slen);
		if (sig == NULL)
			VERIFY_ERROR(ENOMEM);

		p = sig;
		slen = i2d_ECDSA_SIG(ec_sig, &p);

		if (slen == 0)
			VERIFY_ERROR(EINVAL);
	}

	mdctx = EVP_MD_CTX_create();
	if (mdctx == NULL)
		VERIFY_ERROR(ENOMEM);

	/* Initialize the DigestVerify operation using alg */
	if (EVP_DigestVerifyInit(mdctx, NULL, alg, NULL, pkey) != 1)
		VERIFY_ERROR(EINVAL);

	/* Call update with the message */
	if (EVP_DigestVerifyUpdate(mdctx, head, strlen(head)) != 1)
		VERIFY_ERROR(EINVAL);

	/* Now check the sig for validity. */
	if (EVP_DigestVerifyFinal(mdctx, sig, slen) != 1)
		VERIFY_ERROR(EINVAL);

jwt_verify_sha_pem_done:
	if (bufkey)
		BIO_free(bufkey);
	if (pkey)
		EVP_PKEY_free(pkey);
	if (mdctx)
		EVP_MD_CTX_destroy(mdctx);
	if (sig)
		free(sig);
	if (ec_sig)
		ECDSA_SIG_free(ec_sig);

	return ret;
}