Beispiel #1
0
  // Attempt to load private key.
  bool AdbEndpoint::load_key()
  {
    BIO* bp_public;
    BIO* bp_private;

    wxFileName key_file_name(globalSettings()->settings_folder());

    key_file_name.SetName("adb_public.pem");
    bp_public = BIO_new_file(key_file_name.GetFullPath(), "r");
    if (!bp_public) {
      wxLogError("Unable to open public key file %s", key_file_name.GetFullPath());
      return false;
    }
    

    key_file_name.SetName("adb_private.pem");
    bp_private = BIO_new_file(key_file_name.GetFullPath(), "r");
    if (!bp_private) {
      wxLogError("Unable to open private key file %s", key_file_name.GetFullPath());
      BIO_free_all(bp_public);
      return false;
    }

    _key = RSA_new();
    PEM_read_bio_RSAPublicKey(bp_public, &_key, NULL, NULL);
    //PEM_read_bio_RSAPrivateKey(bp_private, &_key, NULL, NULL);
    
    BIO_free_all(bp_private);
    BIO_free_all(bp_public);

    return true;
  }
Beispiel #2
0
void RSATest()
{
    RSA *key = NULL;
    BIO *bio_sec = NULL;
    BIO *bio_pub = NULL;
    FILE *fp_sec = NULL;
    FILE *fp_pub = NULL;
    fopen_s(&fp_sec, "sec.pem", "r");
    fopen_s(&fp_pub, "pub.pem", "r");
    bio_sec = BIO_new_fp(fp_sec, BIO_CLOSE);
    bio_pub = BIO_new_fp(fp_pub, BIO_CLOSE);

    if (!bio_sec || !bio_pub) {
        printf("f****d BIO_new_file\n");
        return;
    }

    if (!PEM_read_bio_RSAPrivateKey(bio_sec, &key, NULL, "")) {
        printf("f****d PEM_read_bio_RSAPrivateKey\n");
        return;
    }

    if (!PEM_read_bio_RSAPublicKey(bio_pub, &key, NULL, "")) {
        printf("f****d PEM_read_bio_RSAPublicKey\n");
        return;
    }

    int len = RSA_size(key);
    unsigned char *buf = new unsigned char[len];
    memset(buf, 0, len);

    if (-1 == RSA_private_encrypt(strlen(RSA_TEXT), (const unsigned char *)RSA_TEXT, buf, key, RSA_PKCS1_PADDING) ) {
        printf("f****d RSA_private_encrypt\n");
        return;
    }

    OutputHexString(buf, len);
    printf("\n");


    /*
    unsigned char *buf_test = new unsigned char[len];
    memset(buf_test, 0, len);

    if (-1 == RSA_public_decrypt(len, buf, buf_test, key, RSA_PKCS1_PADDING) ) {
        printf("f****d RSA_public_decrypt\n");
        return;
    }

    OutputHexString(buf_test, strlen(RSA_TEXT));
    printf("\n");
    delete [] buf_test;
    */

    delete [] buf;
    

    BIO_free(bio_sec);

}
Beispiel #3
0
int RSA_recup_key_pub ( unsigned char* key )
{
    // Déclaration variables
    BIO *keybio = NULL ;

    // On aloue notre object BIO avec la clé
    if ( ( keybio = BIO_new_mem_buf ( key, -1 ) ) == NULL )
    {
        perror ( "Erreur_RSA_recup_key_pub : BIO_new_mem_buf() " ) ;
        fprintf ( stderr, "Code erreur OpenSSL : %lu \n ", ERR_get_error () ) ;
        return 0 ;
    }

    // On lie la clé à la structure RSA
    if ( ( frontale_key = PEM_read_bio_RSAPublicKey ( keybio, &frontale_key, NULL, NULL ) ) == NULL )
    {
        perror ( "Erreur_RSA_recup_key_pub : PEM_read_bio_RSA_PUBKEY() " ) ;
        fprintf ( stderr, "Code erreur OpenSSL : %lu \n ", ERR_get_error () ) ;
        return 0 ;
    }

    // On free notre object BIO
    BIO_free ( keybio ) ;

    // On indique que tout s'est bien déroulé
    return 1 ;
}
Beispiel #4
0
/** Read a PEM-encoded public key from the first <b>len</b> characters of
 * <b>src</b>, and store the result in <b>env</b>.  Return 0 on success, -1 on
 * failure.
 */
int crypto_pk_read_public_key_from_string(crypto_pk_t *env, const char *src,
                                      size_t len)
{
    BIO *b;

//    assert(env);
//    assert(src);
//    assert(len<INT_MAX);

    b = BIO_new(BIO_s_mem()); /* Create a memory BIO */
    if (!b)
        return -1;

    BIO_write(b, src, (int)len);

    if (env->key)
        RSA_free(env->key);
    env->key = PEM_read_bio_RSAPublicKey(b, NULL, NULL, NULL);
    BIO_free(b);
    if (!env->key) {
        err(1, "reading public key from string");
        return -1;
    }

    return 0;
}
Beispiel #5
0
/*
 * rsa public decrypt
*/
char* rsa_decrypt_public(unsigned char *enc,int enc_len,char* private_key_str,int p_len,int *dec_len)
{
    RSA* rsa;
    int rsa_len;
    char *p_de;
    #if 1
   // private_key = rsa_key_seliaze(private_key_str);
    BIO* p_bio = BIO_new_mem_buf(private_key_str, -1);
    rsa = PEM_read_bio_RSAPublicKey(p_bio, NULL, 0, NULL); //
    if ( rsa == NULL ) {
        printf("RSA is NULL\n");
        return NULL;
    }
    #else
    FILE* file=fopen("/tmp/r.key","r");
    rsa=PEM_read_RSA_PUBKEY(file,NULL,NULL,NULL);
    #endif
    rsa_len=RSA_size(rsa);
    p_de=(unsigned char *)calloc(rsa_len+1,1);

    printf("rsa length = %d\n",rsa_len);
    int rc=0;
    rc = RSA_public_decrypt(rsa_len,(unsigned char *)enc,(unsigned char*)p_de,rsa,RSA_PKCS1_PADDING); //RSA_public_decrypt RSA_private_decrypt
    if ( rc<=0 ) {
        int e=ERR_get_error();
        printf("error code is:%s\n",ERR_error_string(e,NULL));
        return NULL;
    }

    RSA_free(rsa);
    printf("plain = %s\n",p_de);
    *dec_len = rc;
    return p_de;
 }
Beispiel #6
0
boolean
an_key_get_public_key (uint8_t *key_label, an_key_t *key)
{
    const char cert_filestr[] = PUBLIC_KEY_LOCATION;
    BIO  *outbio = NULL;
    outbio = BIO_new_fp(stdout, BIO_NOCLOSE);
    int ret;
    char *pub_key = NULL;
    size_t pub_len;

    BIO* rsa_pub_bio = BIO_new_file(cert_filestr, "r");
    RSA* rsa_pub = RSA_new();

    ret = (PEM_read_bio_RSAPublicKey(rsa_pub_bio, &rsa_pub, NULL, NULL)!= NULL);
    if (ret == 0) {
        DEBUG_AN_LOG(AN_LOG_BS_EVENT, AN_DEBUG_INFO, NULL,
                "\n%sFailed to read public key from key pair",an_bs_event);
        return FALSE;
    }
    BIO *pub = BIO_new(BIO_s_mem());
    PEM_write_bio_RSAPublicKey(pub, rsa_pub);
    pub_key = (char*)malloc(BN_num_bits(rsa_pub->n) + 1);
    pub_len = BN_num_bits(rsa_pub->n);
    BIO_read(pub, pub_key, pub_len);
    pub_key[pub_len] = '\0';
    key->data = pub_key;
    key->len = pub_len;
    BIO_free(rsa_pub_bio);
    return TRUE;
}
Beispiel #7
0
/*
 * rsa public key encrypt
 */
char* rsa_encrypt_public(unsigned char*txt,int txt_len,char* public_key_str,int p_len,int* enc_len)
{
	//char *public_key = "-----BEGIN RSA PUBLIC KEY-----\nMIGJAoGBAL331YpDOljAJznk4eNt0TfZJREYypIhWTN/gx0g1iUIaLPlFR7ydjaB\npd9V7G3GvvOf3mGijP+9LjKdgQ8p1pgDW7DeXZk2dTAeQ4hdY287/sw6NFKJxMXA\nFGoUdARObVespCZBdHSqo8kFMAjVGge6ZoH6nAjGzvIfijgsj+2jAgMBAAE=\n-----END RSA PUBLIC KEY-----\n";
	//char * private_key = "-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQC999WKQzpYwCc55OHjbdE32SURGMqSIVkzf4MdINYlCGiz5RUe\n8nY2gaXfVextxr7zn95hooz/vS4ynYEPKdaYA1uw3l2ZNnUwHkOIXWNvO/7MOjRS\nicTFwBRqFHQETm1XrKQmQXR0qqPJBTAI1RoHumaB+pwIxs7yH4o4LI/towIDAQAB\nAoGBAI1ALF2EI2w+ZGxdzcBntXtLUI5n2qfReBwcogcUlWYv3Hp2yb+bFV7uA8IO\nh6AQeYd4xcffL+wwZJtqFb6Ko25XAei8Os3xjb9k5fCcyrmyY+5oeXdQHlcbd/f8\niy8/rOEHZTr4iBXe/8ADlQZlRUkYCblPZ4i4BgzBUB6HzhxhAkEA8wJRx/FjOo6F\noO1aTewbvFIv4Dckqq5j/pBu9fkv1AhMxSfdGnsYcuIn15Y1/RlnpxrmJNWgryvd\n+6LJGDgjWQJBAMgfoINe80YiPCdMoboMd/u1uf1BhwujbiJPSrS40lc3jfyPmHA4\n8hppo8QuELI4rXRE/im4c+zmyphxEyULpVsCQQDnD96JGin65MeE1AsYqpdYwmEJ\ndgVkUXt88wK+2ZizqMyubpAa/M6rdgTiRc7CASUAzF/myEYIKdLh0NAbOk3JAkAE\nxEQVfPh8bipSoU+k19EvzKdOcfYef9kKtirIXTKdYzRdlKoD2kdh+6wr6xD4vcLb\n5xzKr5sLRIAE24SiOEHLAkB1TBlvvvIltttSc9lOpq3UhmtHQJaS32lD2Lk2/zNx\nW6Jbsk+sCQXM0ww4GTCpHMISfokEPtqOPikPcVFs98Oj\n-----END RSA PRIVATE KEY-----\n";
    RSA* rsa;
    int rsa_len;
    char *p_en;
    #if 1
    //public_key = rsa_key_seliaze(public_key_str);
    BIO* p_bio = BIO_new_mem_buf(public_key_str, -1);
    printf("rsa_encrypt is %p \n",p_bio);
    rsa = PEM_read_bio_RSAPublicKey(p_bio, NULL, NULL, NULL); //PEM_read_bio_RSAPrivateKey
    if ( rsa == NULL ) {
        printf("RSA is NULL\n");
        return NULL;
    }
    #else
    FILE* file=fopen("/tmp/r_pub.key","r");
    rsa=PEM_read_RSAPrivateKey(file,NULL,NULL,NULL);//PEM_read_RSAPrivateKey
    #endif
    rsa_len=RSA_size(rsa);
    p_en=(unsigned char *)calloc(rsa_len+1,1);
    printf("rsa length = %d\n",rsa_len);
    int rc=0;
    if((rc=RSA_public_encrypt(txt_len,(unsigned char *)txt,(unsigned char*)p_en,rsa,RSA_PKCS1_PADDING))<=0) {
        int e=ERR_get_error();
        printf("error code is:%s\n",ERR_error_string(e,NULL));
        return NULL;
    }
    printf("rsa length = %d\n",strlen(p_en));
    RSA_free(rsa);
    *enc_len = rc;
    return p_en;
}
Beispiel #8
0
RSAKeyImpl::RSAKeyImpl(
		const std::string& publicKeyFile, 
		const std::string& privateKeyFile, 
		const std::string& privateKeyPassphrase):
	_pRSA(0)
{
	poco_assert_dbg(_pRSA == 0);
	
	_pRSA = RSA_new();
	if (!publicKeyFile.empty())
	{
		BIO* bio = BIO_new(BIO_s_file());
		if (!bio) throw Poco::IOException("Cannot create BIO for reading public key", publicKeyFile);
		int rc = BIO_read_filename(bio, publicKeyFile.c_str());
		if (rc)
		{
			RSA* pubKey = PEM_read_bio_RSAPublicKey(bio, &_pRSA, 0, 0);
			BIO_free(bio);
			if (!pubKey)
			{
				freeRSA();
				throw Poco::FileException("Failed to load public key", publicKeyFile);
			}
		}
		else
		{
			freeRSA();
			throw Poco::FileNotFoundException("Public key file", publicKeyFile);
		}
	}

	if (!privateKeyFile.empty())
	{
		BIO* bio = BIO_new(BIO_s_file());
		if (!bio) throw Poco::IOException("Cannot create BIO for reading private key", privateKeyFile);
		int rc = BIO_read_filename(bio, privateKeyFile.c_str());
		if (rc)
		{
			RSA* privKey = 0;
			if (privateKeyPassphrase.empty())
				privKey = PEM_read_bio_RSAPrivateKey(bio, &_pRSA, 0, 0);
			else
				privKey = PEM_read_bio_RSAPrivateKey(bio, &_pRSA, 0, const_cast<char*>(privateKeyPassphrase.c_str()));
			BIO_free(bio);
			if (!privKey)
			{
				freeRSA();
				throw Poco::FileException("Failed to load private key", privateKeyFile);
			}
		}
		else
		{
			freeRSA();
			throw Poco::FileNotFoundException("Private key file", privateKeyFile);
		}
	}
}
Beispiel #9
0
RSA* get_public_key_from_array(unsigned char* key){
	RSA* rsa=NULL;
	BIO* keybio;
	keybio=BIO_new_mem_buf(key,-1);
	rsa=PEM_read_bio_RSAPublicKey(keybio,&rsa,NULL,NULL);
	if(rsa==NULL){
		printf("\tError creating RSA public key\n");
	}
	BIO_free_all(keybio);
	return rsa;
}
Beispiel #10
0
RSAKeyImpl::RSAKeyImpl(std::istream* pPublicKeyStream,
	std::istream* pPrivateKeyStream,
	const std::string& privateKeyPassphrase): KeyPairImpl("rsa", KT_RSA_IMPL),
		_pRSA(0)
{
	poco_assert_dbg(_pRSA == 0);

	_pRSA = RSA_new();
	if (pPublicKeyStream)
	{
		std::string publicKeyData;
		Poco::StreamCopier::copyToString(*pPublicKeyStream, publicKeyData);
		BIO* bio = BIO_new_mem_buf(const_cast<char*>(publicKeyData.data()), static_cast<int>(publicKeyData.size()));
		if (!bio) throw Poco::IOException("Cannot create BIO for reading public key");
		RSA* publicKey = PEM_read_bio_RSAPublicKey(bio, &_pRSA, 0, 0);
		if (!publicKey)
		{
			int rc = BIO_reset(bio);
			// BIO_reset() normally returns 1 for success and 0 or -1 for failure. 
			// File BIOs are an exception, they return 0 for success and -1 for failure.
			if (rc != 1) throw Poco::FileException("Failed to load public key");
			publicKey = PEM_read_bio_RSA_PUBKEY(bio, &_pRSA, 0, 0);
		}
		BIO_free(bio);
		if (!publicKey)
		{
			freeRSA();
			throw Poco::FileException("Failed to load public key");
		}
	}

	if (pPrivateKeyStream)
	{
		std::string privateKeyData;
		Poco::StreamCopier::copyToString(*pPrivateKeyStream, privateKeyData);
		BIO* bio = BIO_new_mem_buf(const_cast<char*>(privateKeyData.data()), static_cast<int>(privateKeyData.size()));
		if (!bio) throw Poco::IOException("Cannot create BIO for reading private key");
		RSA* privateKey = 0;
		if (privateKeyPassphrase.empty())
			privateKey = PEM_read_bio_RSAPrivateKey(bio, &_pRSA, 0, 0);
		else
			privateKey = PEM_read_bio_RSAPrivateKey(bio, &_pRSA, 0, const_cast<char*>(privateKeyPassphrase.c_str()));
		BIO_free(bio);
		if (!privateKey)
		{
			freeRSA();
			throw Poco::FileException("Failed to load private key");
		}
	}
}
Beispiel #11
0
    public_key::public_key( const bytes& d )
    :my( std::make_shared<detail::pke_impl>() )
    {
       string pem = "-----BEGIN RSA PUBLIC KEY-----\n";
       auto b64 = fc::base64_encode( (const unsigned char*)d.data(), d.size() );
       for( size_t i = 0; i < b64.size(); i += 64 )
           pem += b64.substr( i, 64 ) + "\n";
       pem += "-----END RSA PUBLIC KEY-----\n";
    //   fc::cerr<<pem;

       BIO* mem = (BIO*)BIO_new_mem_buf( (void*)pem.c_str(), pem.size() );
       my->rsa = PEM_read_bio_RSAPublicKey(mem, NULL, NULL, NULL );
       BIO_free(mem);
    }
Beispiel #12
0
/**
 * SHA1WithRSA公钥验签
 *
 * LUA示例:
 * local codec = require('codec')
 * local src = 'something'
 * local sign = [[...]] --BASE64签名
 * local bs = codec.base64_decode(sign)
 * local pem = [[...]] --公钥PEM字符串
 * local type = 1
 * local ok = codec.rsa_public_verify(src, bs, pem, type) --true/false
 */
static int codec_rsa_public_verify(lua_State *L)
{
    size_t srclen, signlen;
    const char *src = luaL_checklstring(L, 1, &srclen);
    const char *sign = luaL_checklstring(L, 2, &signlen);
    char *pem = luaL_checkstring(L, 3);
    int type = luaL_checkint(L, 4);

    SHA_CTX ctx;
    int ctxlen = sizeof(ctx);
    unsigned char sha[SHA_DIGEST_LENGTH];
    memset(sha, 0, SHA_DIGEST_LENGTH);
    if(SHA_Init(&ctx) != 1)
    {
        OPENSSL_cleanse(&ctx, ctxlen);
        return luaL_error(L, "SHA init error");
    }
    if(SHA1_Update(&ctx, src, srclen) != 1)
    {
        OPENSSL_cleanse(&ctx, ctxlen);
        return luaL_error(L, "SHA update error");
    }
    if(SHA1_Final(sha, &ctx) != 1)
    {
        OPENSSL_cleanse(&ctx, ctxlen);
        return luaL_error(L, "SHA update error");
    }
    OPENSSL_cleanse(&ctx, ctxlen);

    BIO *bio = BIO_new_mem_buf((void *)pem, -1);
    if(bio == NULL)
    {
        BIO_free_all(bio);
        return luaL_error(L, "PEM error");
    }
    RSA *rsa = type == 1 ? PEM_read_bio_RSAPublicKey(bio, NULL, NULL, NULL) : PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
    if(rsa == NULL)
    {
        BIO_free_all(bio);
        return luaL_error(L, "RSA read public key error");
    }
    BIO_free_all(bio);

    int ret = RSA_verify(NID_sha1, sha, SHA_DIGEST_LENGTH, (unsigned char *)sign, signlen, rsa);
    RSA_free(rsa);

    lua_pushboolean(L, ret);
    return 1;
}
Beispiel #13
0
RSAKeyImpl::RSAKeyImpl(std::istream* pPublicKeyStream, std::istream* pPrivateKeyStream, const std::string& privateKeyPassphrase):
	_pRSA(0)
{
	poco_assert_dbg(_pRSA == 0);
	
	_pRSA = RSA_new();
	if (pPublicKeyStream)
	{
		std::string publicKeyData;
		Poco::StreamCopier::copyToString(*pPublicKeyStream, publicKeyData);
		BIO* bio = BIO_new_mem_buf(const_cast<char*>(publicKeyData.data()), static_cast<int>(publicKeyData.size()));
		if (!bio) throw Poco::IOException("Cannot create BIO for reading public key");
		RSA* publicKey = PEM_read_bio_RSAPublicKey(bio, &_pRSA, 0, 0);
		if (!publicKey) 
		{
			int rc = BIO_seek(bio, 0);
			if (rc != 0) throw Poco::FileException("Failed to load public key");
			publicKey = PEM_read_bio_RSA_PUBKEY(bio, &_pRSA, 0, 0);
		}
		BIO_free(bio);
		if (!publicKey)
		{
			freeRSA();
			throw Poco::FileException("Failed to load public key");
		}
	}

	if (pPrivateKeyStream)
	{
		std::string privateKeyData;
		Poco::StreamCopier::copyToString(*pPrivateKeyStream, privateKeyData);
		BIO* bio = BIO_new_mem_buf(const_cast<char*>(privateKeyData.data()), static_cast<int>(privateKeyData.size()));
		if (!bio) throw Poco::IOException("Cannot create BIO for reading private key");
		RSA* privateKey = 0;
		if (privateKeyPassphrase.empty())
			privateKey = PEM_read_bio_RSAPrivateKey(bio, &_pRSA, 0, 0);
		else
			privateKey = PEM_read_bio_RSAPrivateKey(bio, &_pRSA, 0, const_cast<char*>(privateKeyPassphrase.c_str()));
		BIO_free(bio);
		if (!privateKey)
		{
			freeRSA();
			throw Poco::FileException("Failed to load private key");
		}
	}
}
QByteArray JulyRSA::getSignature(QByteArray data, QByteArray keyArray)
{
	BIO *bioKey = BIO_new(BIO_s_mem());
	BIO_puts(bioKey,keyArray.data());

	RSA *rsa=NULL;
	rsa=PEM_read_bio_RSAPublicKey(bioKey,&rsa,NULL,NULL);

	if(rsa==NULL)
	{
		BIO *errBIO = BIO_new(BIO_s_mem());
		ERR_print_errors(errBIO);
			char *errData;
			long errSize=BIO_get_mem_data(errBIO, &errData);
		QByteArray errorString(errData,errSize);
		BIO_free(errBIO);
		BIO_free(bioKey);
		RSA_free(rsa);
		return QByteArray();
	}
	int rsaSize=RSA_size(rsa);
	int dataLimit=rsaSize;

	QList<QByteArray> dataList;
	int curDataPos=0;
	while(curDataPos<data.size())
	{
		int endPos=curDataPos+dataLimit-1;
		if(endPos>=data.size())endPos=data.size()-1;
		if(curDataPos<=endPos)
			dataList<<data.mid(curDataPos,endPos-curDataPos+1);
		else break;
		curDataPos=endPos+1;
	}
	QByteArray result;
	for(int n=0;n<dataList.count();n++)
	{
	unsigned char *finalData=(unsigned char *)malloc(rsaSize);
	int outSize=RSA_public_decrypt(dataList.at(n).size(), (unsigned char*)dataList.at(n).constData(), finalData, rsa, RSA_PKCS1_PADDING);
	result.append(QByteArray((char *)finalData,outSize));
	free(finalData);
	}
	BIO_free(bioKey);
	RSA_free(rsa);
	return result;
}
Beispiel #15
0
Result<RSA> RSA::from_pem(Slice pem) {
  init_crypto();

  auto *bio =
      BIO_new_mem_buf(const_cast<void *>(static_cast<const void *>(pem.ubegin())), narrow_cast<int32>(pem.size()));
  if (bio == nullptr) {
    return Status::Error("Cannot create BIO");
  }
  SCOPE_EXIT {
    BIO_free(bio);
  };

  auto *rsa = RSA_new();
  if (rsa == nullptr) {
    return Status::Error("Cannot create RSA");
  }
  SCOPE_EXIT {
    RSA_free(rsa);
  };

  if (!PEM_read_bio_RSAPublicKey(bio, &rsa, nullptr, nullptr)) {
    return Status::Error("Error while reading rsa pubkey");
  }

  if (RSA_size(rsa) != 256) {
    return Status::Error("RSA_size != 256");
  }

  const BIGNUM *n_num;
  const BIGNUM *e_num;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
  n_num = rsa->n;
  e_num = rsa->e;
#else
  RSA_get0_key(rsa, &n_num, &e_num, nullptr);
#endif

  auto n = static_cast<void *>(BN_dup(n_num));
  auto e = static_cast<void *>(BN_dup(e_num));
  if (n == nullptr || e == nullptr) {
    return Status::Error("Cannot dup BIGNUM");
  }

  return RSA(BigNum::from_raw(n), BigNum::from_raw(e));
}
Beispiel #16
0
int COsslKey::setPublicKey( sqbind::CSqBinary *pBin )
{_STT();

	Destroy();

	if ( !pBin || !pBin->getUsed() )
		return 0;

	m_pkey = EVP_PKEY_new();
	if ( !m_pkey )
	{	oexERROR( 0, oexT( "EVP_PKEY_new() failed" ) );
		Destroy();
		return 0;
	} // end if

	BIO *pBio = BIO_new_mem_buf( pBin->_Ptr(), pBin->getUsed() );
	if ( !pBio )
	{	oexERROR( 0, oexT( "BIO_new_mem_buf() failed" ) );
		Destroy();
		return 0;
	} // end if

	RSA *rsa = PEM_read_bio_RSAPublicKey( pBio, oexNULL, oexNULL, (void*)getPasswordPtr() );
	if ( !rsa )
		rsa = PEM_read_bio_RSA_PUBKEY( pBio, oexNULL, oexNULL, (void*)getPasswordPtr() );
	if ( !rsa )
	{	const char *pErr = ERR_reason_error_string( ERR_get_error() );
		oexERROR( 0, oexMks( oexT( "PEM_read_bio_RSAPublicKey(), PEM_read_bio_RSA_PUBKEY() failed : " ), 
							 pErr ? oexMbToStr( pErr ) : oexT( "Unknown" ) ) );
		Destroy();
		return 0;
	} // end if

	// Assign key
	if ( !EVP_PKEY_assign_RSA( m_pkey, rsa ) )
	{	oexERROR( 0, oexT( "EVP_PKEY_assign_RSA() failed" ) );
		Destroy();
		return 0;
	} // end if
	rsa = oexNULL;

	BIO_free( pBio );

	return 1;
}
Beispiel #17
0
int
put_key_pem(int is_public_only, PyObject *py_key_pem,
		PyObject **py_private_key_ccn, PyObject **py_public_key_ccn,
		PyObject **py_public_key_digest)
{
	unsigned char *key_pem;
	Py_ssize_t pem_len;
	RSA *key_rsa = 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_rsa = PEM_read_bio_RSAPublicKey(bio, NULL, NULL, NULL);
	else
		key_rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
	JUMP_IF_NULL(key_rsa, openssl_error);

	r = ccn_keypair_from_rsa(is_public_only, key_rsa, py_private_key_ccn,
			py_public_key_ccn);
	JUMP_IF_NEG(r, error);

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

	RSA_free(key_rsa);

	return 0;

openssl_error:
	err = ERR_get_error();
	PyErr_Format(g_PyExc_CCNKeyError, "Unable to parse key: %s",
			ERR_reason_error_string(err));
error:
	RSA_free(key_rsa);
	BIO_free(bio);
	return -1;
}
Beispiel #18
0
static PyObject *load_key(PyObject *self, PyObject *args)
{
    Py_buffer data;
    BIO *bio = NULL;
    RSA *rsa = NULL;
    RSAObject *result = NULL;

#if PY_MAJOR_VERSION >= 3
    if (!PyArg_ParseTuple(args, "y*:load_key", &data))
        return NULL;
#else
    if (!PyArg_ParseTuple(args, "s*:load_key", &data))
        return NULL;
#endif

    bio = BIO_new_mem_buf(data.buf, data.len);
    if (bio == NULL)
    {
        PyErr_SetString(PyExc_RuntimeError, "BIO_new_mem_buf");
        goto cleanup;
    }

    if (PEM_read_bio_RSAPublicKey(bio, &rsa, NULL, NULL) == NULL)
    {
        PyErr_SetString(PyExc_ValueError, "invalid PKCS1 key");
        goto cleanup;
    }

    result = PyObject_NEW(RSAObject, &RSAType);
    if (result == NULL)
        goto cleanup;

    result->rsa = rsa;
    rsa = NULL;

cleanup:
    if (rsa)
        RSA_free(rsa);
    if (bio)
        BIO_free(bio);
    PyBuffer_Release(&data);

    return (PyObject *) result;
}
Beispiel #19
0
/**
 * RSA公钥加密
 *
 * LUA示例:
 * local codec = require('codec')
 * local src = 'something'
 * local pem = [[...]] --公钥PEM字符串
 * local type = 1
 * local bs = codec.rsa_public_encrypt(src, pem, type)
 * local dst = codec.base64_encode(bs) --BASE64密文
 */
static int codec_rsa_public_encrypt(lua_State *L)
{
    size_t len;
    const char *src = luaL_checklstring(L, 1, &len);
    char *pem = luaL_checkstring(L, 2);
    int type = luaL_checkint(L, 3);

    BIO *bio = BIO_new_mem_buf((void *)pem, -1);
    if(bio == NULL)
    {
        BIO_free_all(bio);
        return luaL_error(L, "PEM error");
    }
    RSA *rsa = type == 1 ? PEM_read_bio_RSAPublicKey(bio, NULL, NULL, NULL) : PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
    if(rsa == NULL)
    {
        BIO_free_all(bio);
        return luaL_error(L, "RSA read public key error");
    }
    BIO_free_all(bio);

    int n = RSA_size(rsa);
    char dst[n];
    memset(dst, 0, n);

    int ret = RSA_public_encrypt(len, (unsigned char *)src, (unsigned char *)dst, rsa, RSA_PKCS1_PADDING);
    if(ret != n)
    {
        RSA_free(rsa);
        BIO_free_all(bio);
        return luaL_error(L, "RSA public encrypt error");
    }
    RSA_free(rsa);

    lua_pushlstring(L, dst, n);
    return 1;
}
Beispiel #20
0
	Private(base::const_byte_span key) : _rsa(PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast<gsl::byte*>(key.data()), key.size()), 0, 0, 0)) {
		if (_rsa) {
			computeFingerprint();
		}
	}
Beispiel #21
0
void PsUpdateDownloader::unpackUpdate() {
    QByteArray packed;
	if (!outputFile.open(QIODevice::ReadOnly)) {
		LOG(("Update Error: cant read updates file!"));
		return fatalFail();
	}
#ifdef Q_OS_WIN // use Lzma SDK for win
	const int32 hSigLen = 128, hShaLen = 20, hPropsLen = LZMA_PROPS_SIZE, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hPropsLen + hOriginalSizeLen; // header
#else
	const int32 hSigLen = 128, hShaLen = 20, hPropsLen = 0, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hOriginalSizeLen; // header
#endif
	QByteArray compressed = outputFile.readAll();
	int32 compressedLen = compressed.size() - hSize;
	if (compressedLen <= 0) {
		LOG(("Update Error: bad compressed size: %1").arg(compressed.size()));
		return fatalFail();
	}
	outputFile.close();

	QString tempDirPath = cWorkingDir() + qsl("tupdates/temp"), readyDirPath = cWorkingDir() + qsl("tupdates/ready");
	deleteDir(tempDirPath);
	deleteDir(readyDirPath);

	QDir tempDir(tempDirPath), readyDir(readyDirPath);
	if (tempDir.exists() || readyDir.exists()) {
		LOG(("Update Error: cant clear tupdates/temp or tupdates/ready dir!"));
		return fatalFail();
	}

	uchar sha1Buffer[20];
	bool goodSha1 = !memcmp(compressed.constData() + hSigLen, hashSha1(compressed.constData() + hSigLen + hShaLen, compressedLen + hPropsLen + hOriginalSizeLen, sha1Buffer), hShaLen);
	if (!goodSha1) {
		LOG(("Update Error: bad SHA1 hash of update file!"));
		return fatalFail();
	}

	RSA *pbKey = PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast<char*>(UpdatesPublicKey), -1), 0, 0, 0);
	if (!pbKey) {
		LOG(("Update Error: cant read public rsa key!"));
		return fatalFail();
	}
    if (RSA_verify(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (const uchar*)(compressed.constData()), hSigLen, pbKey) != 1) { // verify signature
		RSA_free(pbKey);
		LOG(("Update Error: bad RSA signature of update file!"));
		return fatalFail();
    }
	RSA_free(pbKey);

	QByteArray uncompressed;

	int32 uncompressedLen;
	memcpy(&uncompressedLen, compressed.constData() + hSigLen + hShaLen + hPropsLen, hOriginalSizeLen);
	uncompressed.resize(uncompressedLen);

	size_t resultLen = uncompressed.size();
#ifdef Q_OS_WIN // use Lzma SDK for win
	SizeT srcLen = compressedLen;
	int uncompressRes = LzmaUncompress((uchar*)uncompressed.data(), &resultLen, (const uchar*)(compressed.constData() + hSize), &srcLen, (const uchar*)(compressed.constData() + hSigLen + hShaLen), LZMA_PROPS_SIZE);
	if (uncompressRes != SZ_OK) {
		LOG(("Update Error: could not uncompress lzma, code: %1").arg(uncompressRes));
		return fatalFail();
	}
#else
	lzma_stream stream = LZMA_STREAM_INIT;

	lzma_ret ret = lzma_stream_decoder(&stream, UINT64_MAX, LZMA_CONCATENATED);
	if (ret != LZMA_OK) {
		const char *msg;
		switch (ret) {
			case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
			case LZMA_OPTIONS_ERROR: msg = "Specified preset is not supported"; break;
			case LZMA_UNSUPPORTED_CHECK: msg = "Specified integrity check is not supported"; break;
			default: msg = "Unknown error, possibly a bug"; break;
		}
		LOG(("Error initializing the decoder: %1 (error code %2)").arg(msg).arg(ret));
		return fatalFail();
	}

	stream.avail_in = compressedLen;
	stream.next_in = (uint8_t*)(compressed.constData() + hSize);
	stream.avail_out = resultLen;
	stream.next_out = (uint8_t*)uncompressed.data();

	lzma_ret res = lzma_code(&stream, LZMA_FINISH);
	if (stream.avail_in) {
		LOG(("Error in decompression, %1 bytes left in _in of %2 whole.").arg(stream.avail_in).arg(compressedLen));
		return fatalFail();
	} else if (stream.avail_out) {
		LOG(("Error in decompression, %1 bytes free left in _out of %2 whole.").arg(stream.avail_out).arg(resultLen));
		return fatalFail();
	}
	lzma_end(&stream);
	if (res != LZMA_OK && res != LZMA_STREAM_END) {
		const char *msg;
		switch (res) {
			case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
			case LZMA_FORMAT_ERROR: msg = "The input data is not in the .xz format"; break;
			case LZMA_OPTIONS_ERROR: msg = "Unsupported compression options"; break;
			case LZMA_DATA_ERROR: msg = "Compressed file is corrupt"; break;
			case LZMA_BUF_ERROR: msg = "Compressed data is truncated or otherwise corrupt"; break;
			default: msg = "Unknown error, possibly a bug"; break;
		}
		LOG(("Error in decompression: %1 (error code %2)").arg(msg).arg(res));
		return fatalFail();
	}
#endif

	tempDir.mkdir(tempDir.absolutePath());

	quint32 version;
	{
		QBuffer buffer(&uncompressed);
		buffer.open(QIODevice::ReadOnly);
		QDataStream stream(&buffer);
		stream.setVersion(QDataStream::Qt_5_1);

		stream >> version;
		if (stream.status() != QDataStream::Ok) {
			LOG(("Update Error: cant read version from downloaded stream, status: %1").arg(stream.status()));
			return fatalFail();
		}
		if (version <= AppVersion) {
			LOG(("Update Error: downloaded version %1 is not greater, than mine %2").arg(version).arg(AppVersion));
			return fatalFail();
		}

		quint32 filesCount;
		stream >> filesCount;
		if (stream.status() != QDataStream::Ok) {
			LOG(("Update Error: cant read files count from downloaded stream, status: %1").arg(stream.status()));
			return fatalFail();
		}
		if (!filesCount) {
			LOG(("Update Error: update is empty!"));
			return fatalFail();
		}
		for (uint32 i = 0; i < filesCount; ++i) {
			QString relativeName;
			quint32 fileSize;
			QByteArray fileInnerData;
			bool executable = false;

			stream >> relativeName >> fileSize >> fileInnerData;
#if defined Q_OS_MAC || defined Q_OS_LINUX
			stream >> executable;
#endif
			if (stream.status() != QDataStream::Ok) {
				LOG(("Update Error: cant read file from downloaded stream, status: %1").arg(stream.status()));
				return fatalFail();
			}
			if (fileSize != quint32(fileInnerData.size())) {
				LOG(("Update Error: bad file size %1 not matching data size %2").arg(fileSize).arg(fileInnerData.size()));
				return fatalFail();
			}

			QFile f(tempDirPath + '/' + relativeName);
			if (!QDir().mkpath(QFileInfo(f).absolutePath())) {
				LOG(("Update Error: cant mkpath for file '%1'").arg(tempDirPath + '/' + relativeName));
				return fatalFail();
			}
			if (!f.open(QIODevice::WriteOnly)) {
				LOG(("Update Error: cant open file '%1' for writing").arg(tempDirPath + '/' + relativeName));
				return fatalFail();
			}
			if (f.write(fileInnerData) != fileSize) {
				f.close();
				LOG(("Update Error: cant write file '%1'").arg(tempDirPath + '/' + relativeName));
				return fatalFail();
			}
			f.close();
			if (executable) {
				QFileDevice::Permissions p = f.permissions();
				p |= QFileDevice::ExeOwner | QFileDevice::ExeUser | QFileDevice::ExeGroup | QFileDevice::ExeOther;
				f.setPermissions(p);
			}
		}

		// create tdata/version file
		tempDir.mkdir(QDir(tempDirPath + qsl("/tdata")).absolutePath());
		std::wstring versionString = ((version % 1000) ? QString("%1.%2.%3").arg(int(version / 1000000)).arg(int((version % 1000000) / 1000)).arg(int(version % 1000)) : QString("%1.%2").arg(int(version / 1000000)).arg(int((version % 1000000) / 1000))).toStdWString();

		VerInt versionNum = VerInt(version), versionLen = VerInt(versionString.size() * sizeof(VerChar));
		VerChar versionStr[32];
		memcpy(versionStr, versionString.c_str(), versionLen);

		QFile fVersion(tempDirPath + qsl("/tdata/version"));
		if (!fVersion.open(QIODevice::WriteOnly)) {
			LOG(("Update Error: cant write version file '%1'").arg(tempDirPath + qsl("/version")));
			return fatalFail();
		}
		fVersion.write((const char*)&versionNum, sizeof(VerInt));
		fVersion.write((const char*)&versionLen, sizeof(VerInt));
		fVersion.write((const char*)&versionStr[0], versionLen);
		fVersion.close();
	}

	if (!tempDir.rename(tempDir.absolutePath(), readyDir.absolutePath())) {
		LOG(("Update Error: cant rename temp dir '%1' to ready dir '%2'").arg(tempDir.absolutePath()).arg(readyDir.absolutePath()));
		return fatalFail();
	}
	deleteDir(tempDirPath);
	outputFile.remove();

    emit App::app()->updateReady();
}
CFMutableDictionaryRef SDMMD__CreatePairingMaterial(CFDataRef devicePubkey)
{
	CFMutableDictionaryRef record = NULL;
	RSA *rsaBIOData = NULL;
	BIO *deviceBIO = SDMMD__create_bio_from_data(devicePubkey);
	if (deviceBIO) {
		PEM_read_bio_RSAPublicKey(deviceBIO, &rsaBIOData, NULL, NULL);
		BIO_free(deviceBIO);
	}
	else {
		printf("Could not decode device public key\\n");
	}

	RSA *rootKeyPair = RSA_generate_key(2048, 65537, NULL, NULL);
	if (!rootKeyPair) {
		printf("Could not allocate root key pair\n");
	}

	RSA *hostKeyPair = RSA_generate_key(2048, 65537, NULL, NULL);
	if (!hostKeyPair) {
		printf("Could not allocate host key pair\n");
	}

	sdmmd_return_t result = kAMDSuccess;

	EVP_PKEY *rootEVP = EVP_PKEY_new();
	if (!rootEVP) {
		printf("Could not allocate root EVP key\\n");
	}
	else {
		result = EVP_PKEY_assign(rootEVP, EVP_CTRL_RAND_KEY, PtrCast(rootKeyPair, char *));
		if (!result) {
			printf("Could not assign root key pair\n");
		}
	}

	EVP_PKEY *hostEVP = EVP_PKEY_new();
	if (!hostEVP) {
		printf("Could not allocate host EVP key\\n");
	}
	else {
		result = EVP_PKEY_assign(hostEVP, EVP_CTRL_RAND_KEY, PtrCast(hostKeyPair, char *));
		if (!result) {
			printf("Could not assign host key pair\n");
		}
	}

	EVP_PKEY *deviceEVP = EVP_PKEY_new();
	if (!deviceEVP) {
		printf("Could not allocate device EVP key\\n");
	}
	else {
		result = EVP_PKEY_assign(deviceEVP, EVP_CTRL_RAND_KEY, PtrCast(rsaBIOData, char *));
		if (!result) {
			printf("Could not assign device key pair\n");
		}
	}

	X509 *rootX509 = X509_new();
	if (!rootX509) {
		printf("Could not create root X509\\n");
	}
	else {
		X509_set_pubkey(rootX509, rootEVP);
		X509_set_version(rootX509, 2);

		ASN1_INTEGER *rootSerial = X509_get_serialNumber(rootX509);
		ASN1_INTEGER_set(rootSerial, 0);

		ASN1_TIME *rootAsn1time = ASN1_TIME_new();
		ASN1_TIME_set(rootAsn1time, 0);
		X509_set_notBefore(rootX509, rootAsn1time);
		ASN1_TIME_set(rootAsn1time, 0x12cc0300); // 60 sec * 60 minutes * 24 hours * 365 days * 10 years
		X509_set_notAfter(rootX509, rootAsn1time);
		ASN1_TIME_free(rootAsn1time);

		SDMMD__add_ext(rootX509, NID_basic_constraints, "critical,CA:TRUE");
		SDMMD__add_ext(rootX509, NID_subject_key_identifier, "hash");

		result = X509_sign(rootX509, rootEVP, EVP_sha1());
		if (!result) {
			printf("Could not sign root cert\\n");
		}
	}

	X509 *hostX509 = X509_new();
	if (!hostX509) {
		printf("Could not create host X509\\n");
	}
	else {
		X509_set_pubkey(hostX509, hostEVP);
		X509_set_version(hostX509, 2);

		ASN1_INTEGER *hostSerial = X509_get_serialNumber(hostX509);
		ASN1_INTEGER_set(hostSerial, 0);

		ASN1_TIME *hostAsn1time = ASN1_TIME_new();
		ASN1_TIME_set(hostAsn1time, 0);
		X509_set_notBefore(hostX509, hostAsn1time);
		ASN1_TIME_set(hostAsn1time, 0x12cc0300); // 60 sec * 60 minutes * 24 hours * 365 days * 10 years
		X509_set_notAfter(hostX509, hostAsn1time);
		ASN1_TIME_free(hostAsn1time);

		SDMMD__add_ext(hostX509, NID_basic_constraints, "critical,CA:FALSE");
		SDMMD__add_ext(hostX509, NID_subject_key_identifier, "hash");
		SDMMD__add_ext(hostX509, NID_key_usage, "critical,digitalSignature,keyEncipherment");

		result = X509_sign(hostX509, rootEVP, EVP_sha1());
		if (!result) {
			printf("Could not sign host cert\\n");
		}
	}

	X509 *deviceX509 = X509_new();
	if (!deviceX509) {
		printf("Could not create device X509\\n");
	}
	else {
		X509_set_pubkey(deviceX509, deviceEVP);
		X509_set_version(deviceX509, 2);

		ASN1_INTEGER *deviceSerial = X509_get_serialNumber(deviceX509);
		ASN1_INTEGER_set(deviceSerial, 0);

		ASN1_TIME *deviceAsn1time = ASN1_TIME_new();
		ASN1_TIME_set(deviceAsn1time, 0);
		X509_set_notBefore(deviceX509, deviceAsn1time);
		ASN1_TIME_set(deviceAsn1time, 0x12cc0300); // 60 sec * 60 minutes * 24 hours * 365 days * 10 years
		X509_set_notAfter(deviceX509, deviceAsn1time);
		ASN1_TIME_free(deviceAsn1time);

		SDMMD__add_ext(deviceX509, NID_basic_constraints, "critical,CA:FALSE");
		SDMMD__add_ext(deviceX509, NID_subject_key_identifier, "hash");
		SDMMD__add_ext(deviceX509, NID_key_usage, "critical,digitalSignature,keyEncipherment");

		result = X509_sign(deviceX509, rootEVP, EVP_sha1());
		if (!result) {
			printf("Could not sign device cert\\n");
		}
	}

	CFDataRef rootCert = SDMMD_CreateDataFromX509Certificate(rootX509);
	CFDataRef hostCert = SDMMD_CreateDataFromX509Certificate(hostX509);
	CFDataRef deviceCert = SDMMD_CreateDataFromX509Certificate(deviceX509);
	CFDataRef rootPrivKey = SDMMD_CreateDataFromPrivateKey(rootEVP);
	CFDataRef hostPrivKey = SDMMD_CreateDataFromPrivateKey(hostEVP);
	CFStringRef hostId = SDMMD_CreateUUID();

	record = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
	if (record) {
		CFDictionarySetValue(record, CFSTR("RootCertificate"), rootCert);

		CFDictionarySetValue(record, CFSTR("HostCertificate"), hostCert);

		CFDictionarySetValue(record, CFSTR("DeviceCertificate"), deviceCert);

		CFDictionarySetValue(record, CFSTR("RootPrivateKey"), rootPrivKey);

		CFDictionarySetValue(record, CFSTR("HostPrivateKey"), hostPrivKey);

		CFDictionarySetValue(record, CFSTR("HostID"), hostId);
	}
	CFSafeRelease(rootCert);
	CFSafeRelease(hostCert);
	CFSafeRelease(deviceCert);
	CFSafeRelease(rootPrivKey);
	CFSafeRelease(hostPrivKey);
	CFSafeRelease(hostId);

	Safe(EVP_PKEY_free, rootEVP);
	Safe(EVP_PKEY_free, hostEVP);
	Safe(EVP_PKEY_free, deviceEVP);
	Safe(X509_free, rootX509);
	Safe(X509_free, hostX509);
	Safe(X509_free, deviceX509);

	return record;
}
Beispiel #23
0
int main(int argc, char *argv[])
{
	QString workDir;
#ifdef Q_OS_MAC
    if (QDir(QString()).absolutePath() == "/") {
		QString first = argc ? QString::fromLocal8Bit(argv[0]) : QString();
		if (!first.isEmpty()) {
			QFileInfo info(first);
			if (info.exists()) {
				QDir result(info.absolutePath() + "/../../..");
				workDir = result.absolutePath() + '/';
			}
		}
	}
#endif

	QString remove;
	int version = 0;
	QFileInfoList files;
	for (int i = 0; i < argc; ++i) {
		if (string("-path") == argv[i] && i + 1 < argc) {
			QString path = workDir + QString(argv[i + 1]);
			QFileInfo info(path);
			files.push_back(info);
			if (remove.isEmpty()) remove = info.canonicalPath() + "/";
		} else if (string("-version") == argv[i] && i + 1 < argc) {
			version = QString(argv[i + 1]).toInt();
		} else if (string("-dev") == argv[i]) {
			DevChannel = true;
		} else if (string("-beta") == argv[i] && i + 1 < argc) {
			BetaVersion = QString(argv[i + 1]).toULongLong();
			if (BetaVersion > version * 1000ULL && BetaVersion < (version + 1) * 1000ULL) {
				DevChannel = false;
				BetaSignature = countBetaVersionSignature(BetaVersion);
				if (BetaSignature.isEmpty()) {
					return -1;
				}
			} else {
				cout << "Bad -beta param value passed, should be for the same version: " << version << ", beta: " << BetaVersion << "\n";
				return -1;
			}
		}
	}

	if (files.isEmpty() || remove.isEmpty() || version <= 1016 || version > 999999999) {
#ifdef Q_OS_WIN
		cout << "Usage: Packer.exe -path {file} -version {version} OR Packer.exe -path {dir} -version {version}\n";
#elif defined Q_OS_MAC
		cout << "Usage: Packer.app -path {file} -version {version} OR Packer.app -path {dir} -version {version}\n";
#else
		cout << "Usage: Packer -path {file} -version {version} OR Packer -path {dir} -version {version}\n";
#endif
		return -1;
	}

	bool hasDirs = true;
	while (hasDirs) {
		hasDirs = false;
		for (QFileInfoList::iterator i = files.begin(); i != files.end(); ++i) {
			QFileInfo info(*i);
			QString fullPath = info.canonicalFilePath();
			if (info.isDir()) {
				hasDirs = true;
				files.erase(i);
				QDir d = QDir(info.absoluteFilePath());
				QString fullDir = d.canonicalPath();
				QStringList entries = d.entryList(QDir::Files | QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot);
				files.append(d.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot));
				break;
			} else if (!info.isReadable()) {
				cout << "Can't read: " << info.absoluteFilePath().toUtf8().constData() << "\n";
				return -1;
			} else if (info.isHidden()) {
				hasDirs = true;
				files.erase(i);
				break;
			}
		}
	}
	for (QFileInfoList::iterator i = files.begin(); i != files.end(); ++i) {
		QFileInfo info(*i);
		if (!info.canonicalFilePath().startsWith(remove)) {
			cout << "Can't find '" << remove.toUtf8().constData() << "' in file '" << info.canonicalFilePath().toUtf8().constData() << "' :(\n";
			return -1;
		}
	}

	QByteArray result;
	{
		QBuffer buffer(&result);
		buffer.open(QIODevice::WriteOnly);
		QDataStream stream(&buffer);
		stream.setVersion(QDataStream::Qt_5_1);

		if (BetaVersion) {
			stream << quint32(0x7FFFFFFF);
			stream << quint64(BetaVersion);
		} else {
			stream << quint32(version);
		}

		stream << quint32(files.size());
		cout << "Found " << files.size() << " file" << (files.size() == 1 ? "" : "s") << "..\n";
		for (QFileInfoList::iterator i = files.begin(); i != files.end(); ++i) {
			QFileInfo info(*i);
			QString fullName = info.canonicalFilePath();
			QString name = fullName.mid(remove.length());
			cout << name.toUtf8().constData() << " (" << info.size() << ")\n";

			QFile f(fullName);
			if (!f.open(QIODevice::ReadOnly)) {
				cout << "Can't open '" << fullName.toUtf8().constData() << "' for read..\n";
				return -1;
			}
			QByteArray inner = f.readAll();
			stream << name << quint32(inner.size()) << inner;
#if defined Q_OS_MAC || defined Q_OS_LINUX
			stream << (QFileInfo(fullName).isExecutable() ? true : false);
#endif
		}
		if (stream.status() != QDataStream::Ok) {
			cout << "Stream status is bad: " << stream.status() << "\n";
			return -1;
		}
	}

	int32 resultSize = result.size();
	cout << "Compression start, size: " << resultSize << "\n";

	QByteArray compressed, resultCheck;
#ifdef Q_OS_WIN // use Lzma SDK for win
	const int32 hSigLen = 128, hShaLen = 20, hPropsLen = LZMA_PROPS_SIZE, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hPropsLen + hOriginalSizeLen; // header

	compressed.resize(hSize + resultSize + 1024 * 1024); // rsa signature + sha1 + lzma props + max compressed size

	size_t compressedLen = compressed.size() - hSize;
	size_t outPropsSize = LZMA_PROPS_SIZE;
	uchar *_dest = (uchar*)(compressed.data() + hSize);
	size_t *_destLen = &compressedLen;
	const uchar *_src = (const uchar*)(result.constData());
	size_t _srcLen = result.size();
	uchar *_outProps = (uchar*)(compressed.data() + hSigLen + hShaLen);
	int res = LzmaCompress(_dest, _destLen, _src, _srcLen, _outProps, &outPropsSize, 9, 64 * 1024 * 1024, 4, 0, 2, 273, 2);
	if (res != SZ_OK) {
		cout << "Error in compression: " << res << "\n";
		return -1;
	}
	compressed.resize(int(hSize + compressedLen));
	memcpy(compressed.data() + hSigLen + hShaLen + hPropsLen, &resultSize, hOriginalSizeLen);

	cout << "Compressed to size: " << compressedLen << "\n";

	cout << "Checking uncompressed..\n";

	int32 resultCheckLen;
	memcpy(&resultCheckLen, compressed.constData() + hSigLen + hShaLen + hPropsLen, hOriginalSizeLen);
	if (resultCheckLen <= 0 || resultCheckLen > 1024 * 1024 * 1024) {
		cout << "Bad result len: " << resultCheckLen << "\n";
		return -1;
	}
	resultCheck.resize(resultCheckLen);

	size_t resultLen = resultCheck.size();
	SizeT srcLen = compressedLen;
	int uncompressRes = LzmaUncompress((uchar*)resultCheck.data(), &resultLen, (const uchar*)(compressed.constData() + hSize), &srcLen, (const uchar*)(compressed.constData() + hSigLen + hShaLen), LZMA_PROPS_SIZE);
	if (uncompressRes != SZ_OK) {
		cout << "Uncompress failed: " << uncompressRes << "\n";
		return -1;
	}
	if (resultLen != size_t(result.size())) {
		cout << "Uncompress bad size: " << resultLen << ", was: " << result.size() << "\n";
		return -1;
	}
#else // use liblzma for others
	const int32 hSigLen = 128, hShaLen = 20, hPropsLen = 0, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hOriginalSizeLen; // header

	compressed.resize(hSize + resultSize + 1024 * 1024); // rsa signature + sha1 + lzma props + max compressed size

	size_t compressedLen = compressed.size() - hSize;

	lzma_stream stream = LZMA_STREAM_INIT;

	int preset = 9 | LZMA_PRESET_EXTREME;
	lzma_ret ret = lzma_easy_encoder(&stream, preset, LZMA_CHECK_CRC64);
	if (ret != LZMA_OK) {
		const char *msg;
		switch (ret) {
			case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
			case LZMA_OPTIONS_ERROR: msg = "Specified preset is not supported"; break;
			case LZMA_UNSUPPORTED_CHECK: msg = "Specified integrity check is not supported"; break;
			default: msg = "Unknown error, possibly a bug"; break;
		}
		cout << "Error initializing the encoder: " << msg << " (error code " << ret << ")\n";
		return -1;
	}

	stream.avail_in = resultSize;
	stream.next_in = (uint8_t*)result.constData();
	stream.avail_out = compressedLen;
	stream.next_out = (uint8_t*)(compressed.data() + hSize);

	lzma_ret res = lzma_code(&stream, LZMA_FINISH);
	compressedLen -= stream.avail_out;
	lzma_end(&stream);
	if (res != LZMA_OK && res != LZMA_STREAM_END) {
		const char *msg;
		switch (res) {
			case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
			case LZMA_DATA_ERROR: msg = "File size limits exceeded"; break;
			default: msg = "Unknown error, possibly a bug"; break;
		}
		cout << "Error in compression: " << msg << " (error code " << res << ")\n";
		return -1;
	}

	compressed.resize(int(hSize + compressedLen));
	memcpy(compressed.data() + hSigLen + hShaLen, &resultSize, hOriginalSizeLen);

	cout << "Compressed to size: " << compressedLen << "\n";

	cout << "Checking uncompressed..\n";

	int32 resultCheckLen;
	memcpy(&resultCheckLen, compressed.constData() + hSigLen + hShaLen, hOriginalSizeLen);
	if (resultCheckLen <= 0 || resultCheckLen > 1024 * 1024 * 1024) {
		cout << "Bad result len: " << resultCheckLen << "\n";
		return -1;
	}
	resultCheck.resize(resultCheckLen);

	size_t resultLen = resultCheck.size();

	stream = LZMA_STREAM_INIT;

	ret = lzma_stream_decoder(&stream, UINT64_MAX, LZMA_CONCATENATED);
	if (ret != LZMA_OK) {
		const char *msg;
		switch (ret) {
			case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
			case LZMA_OPTIONS_ERROR: msg = "Specified preset is not supported"; break;
			case LZMA_UNSUPPORTED_CHECK: msg = "Specified integrity check is not supported"; break;
			default: msg = "Unknown error, possibly a bug"; break;
		}
		cout << "Error initializing the decoder: " << msg << " (error code " << ret << ")\n";
		return -1;
	}

	stream.avail_in = compressedLen;
	stream.next_in = (uint8_t*)(compressed.constData() + hSize);
	stream.avail_out = resultLen;
	stream.next_out = (uint8_t*)resultCheck.data();

	res = lzma_code(&stream, LZMA_FINISH);
	if (stream.avail_in) {
		cout << "Error in decompression, " << stream.avail_in << " bytes left in _in of " << compressedLen << " whole.\n";
		return -1;
	} else if (stream.avail_out) {
		cout << "Error in decompression, " << stream.avail_out << " bytes free left in _out of " << resultLen << " whole.\n";
		return -1;
	}
	lzma_end(&stream);
	if (res != LZMA_OK && res != LZMA_STREAM_END) {
		const char *msg;
		switch (res) {
			case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
			case LZMA_FORMAT_ERROR: msg = "The input data is not in the .xz format"; break;
			case LZMA_OPTIONS_ERROR: msg = "Unsupported compression options"; break;
			case LZMA_DATA_ERROR: msg = "Compressed file is corrupt"; break;
			case LZMA_BUF_ERROR: msg = "Compressed data is truncated or otherwise corrupt"; break;
			default: msg = "Unknown error, possibly a bug"; break;
		}
		cout << "Error in decompression: " << msg << " (error code " << res << ")\n";
		return -1;
	}
#endif
	if (memcmp(result.constData(), resultCheck.constData(), resultLen)) {
		cout << "Data differ :(\n";
		return -1;
	}
	/**/
	result = resultCheck = QByteArray();

	cout << "Counting SHA1 hash..\n";

	uchar sha1Buffer[20];
	memcpy(compressed.data() + hSigLen, hashSha1(compressed.constData() + hSigLen + hShaLen, uint32(compressedLen + hPropsLen + hOriginalSizeLen), sha1Buffer), hShaLen); // count sha1

	uint32 siglen = 0;

	cout << "Signing..\n";
	RSA *prKey = PEM_read_bio_RSAPrivateKey(BIO_new_mem_buf(const_cast<char*>((DevChannel || BetaVersion) ? PrivateDevKey : PrivateKey), -1), 0, 0, 0);
	if (!prKey) {
		cout << "Could not read RSA private key!\n";
		return -1;
	}
	if (RSA_size(prKey) != hSigLen) {
		cout << "Bad private key, size: " << RSA_size(prKey) << "\n";
		RSA_free(prKey);
		return -1;
	}
	if (RSA_sign(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (uchar*)(compressed.data()), &siglen, prKey) != 1) { // count signature
		cout << "Signing failed!\n";
		RSA_free(prKey);
		return -1;
	}
	RSA_free(prKey);

	if (siglen != hSigLen) {
		cout << "Bad signature length: " << siglen << "\n";
		return -1;
	}

	cout << "Checking signature..\n";
	RSA *pbKey = PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast<char*>((DevChannel || BetaVersion) ? PublicDevKey : PublicKey), -1), 0, 0, 0);
	if (!pbKey) {
		cout << "Could not read RSA public key!\n";
		return -1;
	}
	if (RSA_verify(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (const uchar*)(compressed.constData()), siglen, pbKey) != 1) { // verify signature
		RSA_free(pbKey);
		cout << "Signature verification failed!\n";
		return -1;
	}
	cout << "Signature verified!\n";
	RSA_free(pbKey);
#ifdef Q_OS_WIN
	QString outName(QString("tupdate%1").arg(BetaVersion ? BetaVersion : version));
#elif defined Q_OS_MAC
	QString outName(QString("tmacupd%1").arg(BetaVersion ? BetaVersion : version));
#elif defined Q_OS_LINUX32
    QString outName(QString("tlinux32upd%1").arg(BetaVersion ? BetaVersion : version));
#elif defined Q_OS_LINUX64
    QString outName(QString("tlinuxupd%1").arg(BetaVersion ? BetaVersion : version));
#else
#error Unknown platform!
#endif
	if (BetaVersion) {
		outName += "_" + BetaSignature;
	}
	QFile out(outName);
	if (!out.open(QIODevice::WriteOnly)) {
		cout << "Can't open '" << outName.toUtf8().constData() << "' for write..\n";
		return -1;
	}
	out.write(compressed);
	out.close();

	if (BetaVersion) {
		QString keyName(QString("tbeta_%1_key").arg(BetaVersion));
		QFile key(keyName);
		if (!key.open(QIODevice::WriteOnly)) {
			cout << "Can't open '" << keyName.toUtf8().constData() << "' for write..\n";
			return -1;
		}
		key.write(BetaSignature.toUtf8());
		key.close();
	}

	cout << "Update file '" << outName.toUtf8().constData() << "' written successfully!\n";

	return 0;
}
Beispiel #24
0
	Impl(const char *key) : rsa(PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast<char*>(key), -1), 0, 0, 0)) {
	}
Beispiel #25
0
int
main() {
    BIO *bio;
    RSA *rsa=0, *rsa_pub, *rsa_priv=0;
    char buf[4096], enc[4096], dec[4096];
    BUF_MEM *ptr;
    int len, enc_len, dec_len;
    int i;
    BF_KEY key;
    char ivec_orig[8] = {1, 2, 3, 4, 5, 6, 7, 8}, ivec[8];


    do {
        //OpenSSL_add_all_algorithms();
        //OpenSSL_add_all_ciphers();
        //OpenSSL_add_all_digests();

        printf("generate_key:\n");
        rsa = RSA_generate_key(1024, 3, gen_cb, 0);
        printf("\n");

        printf("pem public key:\n");
        bio = BIO_new(BIO_s_mem());
        i = PEM_write_bio_RSAPublicKey(bio, rsa);
        BIO_flush(bio);
        i = BIO_get_mem_ptr(bio, &ptr);
        printf("pem public key len=%d\n", ptr->length);
        fwrite(ptr->data, ptr->length, 1, stdout);
        len = ptr->length;
        memcpy(buf, ptr->data, len);
        BIO_free(bio);
        printf("\n");

        bio = BIO_new_mem_buf(buf, len);
        rsa_pub = PEM_read_bio_RSAPublicKey(bio, 0, 0, 0);
        BIO_free(bio);

        printf("pem private key:\n");
        bio = BIO_new(BIO_s_mem());
        i = PEM_write_bio_RSAPrivateKey(bio, rsa, 0, 0, 0, 0, 0);
        BIO_flush(bio);
        i = BIO_get_mem_ptr(bio, &ptr);
        printf("pem private key i=%d len=%d\n", i, ptr->length);
        fwrite(ptr->data, ptr->length, 1, stdout);
        len = ptr->length;
        memcpy(buf, ptr->data, len);
        BIO_free(bio);
        printf("\n");

        bio = BIO_new_mem_buf(buf, len);
        rsa_priv = PEM_read_bio_RSAPrivateKey(bio, 0, 0, 0);
        BIO_free(bio);

        /* encrypt */

        printf("buffer:\n");
        len = sprintf(buf, "1234567890123456");
        len = 128/8;
        RAND_bytes(buf, len);
        printf("buf_len=%d\n", len);
        //printf("%s", dec);
        for(i=0; i<len; i++) {
            printf("%02x", (unsigned int)buf[i]&0xff);
        }
        printf("\n");


        printf("public_encrypt:\n");
        memset(enc, 0, sizeof(enc));
        enc_len = RSA_public_encrypt(len, buf, enc, rsa_pub, RSA_PKCS1_OAEP_PADDING);
        if( enc_len < 0 ) {
            printf("err=%ld\n", ERR_get_error());
            break;

        }
        printf("enc_len=%d\n", enc_len);
        for(i=0; i<enc_len; i++) {
            printf("%02x", (unsigned int)enc[i]&0xff);
        }
        printf("\n");


        printf("public_decrypt:\n");
        memset(dec, 0, sizeof(dec));
        dec_len = RSA_private_decrypt(enc_len, enc, dec, rsa_priv, RSA_PKCS1_OAEP_PADDING);
        if( dec_len < 0 ) {
            printf("err=%ld\n", ERR_get_error());
            break;

        }
        printf("dec_len=%d\n", dec_len);
        for(i=0; i<dec_len; i++) {
            printf("%02x", (unsigned int)dec[i]&0xff);
        }
        printf("\n");

        // blowfish
        BF_set_key(&key, dec_len, dec);

        i = 0;
        memcpy(ivec, ivec_orig, 8);
        memset(buf, 0, sizeof(buf));
        BF_cfb64_encrypt(enc, buf, enc_len, &key, ivec, &i, BF_ENCRYPT);

        printf("BF_cfb64_encrypt:\n");
        for(i=0; i<enc_len; i++) {
            printf("%02x", (unsigned int)buf[i]&0xff);
        }
        printf("\n");

        i = 0;
        memcpy(ivec, ivec_orig, 8);
        memset(enc, 0, sizeof(buf));
        BF_cfb64_encrypt(buf, enc, enc_len, &key, ivec, &i, BF_DECRYPT);

        printf("BF_cfb64_decrypt:\n");
        for(i=0; i<enc_len; i++) {
            printf("%02x", (unsigned int)enc[i]&0xff);
        }
        printf("\n");

    } while(0);

    if( rsa ) {
        RSA_free(rsa);
    }


    return 0;
}
Beispiel #26
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);
}
Beispiel #27
0
int validate_token(bstring token)
{
    int i;

    OpenSSL_add_all_algorithms();

    struct bstrList *parts = bsplit(token, '|');

    dictionary *dict = dictionary_new(10);

    bstring sig = bfromcstr("sig");
    bstring to_sign = bfromcstr("");
    
    for (i = 0; i < parts->qty; i++)
    {
	printf("%d: %s\n", i, parts->entry[i]->data);

	struct bstrList *x = bsplit(parts->entry[i], '=');
	if (x->qty == 2)
	{
	    if (bstrcmp(x->entry[0], sig) != 0)
	    {
		if (blength(to_sign) > 0)
		    bconchar(to_sign, '|');
		bconcat(to_sign, parts->entry[i]);
	    }
	    dictionary_set(dict, bdata(x->entry[0]), bdata(x->entry[1]));
	}
	bstrListDestroy(x);
    }
    bstrListDestroy(parts);
    parts = 0;
    bdestroy(sig);
    
    dictionary_dump(dict, stdout);
    printf("to sign: '%s'\n", bdata(to_sign));

    // Check signing subject (need to know the valid values)

    char *subj = dictionary_get(dict, "SigningSubject", 0);
    if (!subj)
    {
	fprintf(stderr, "could not get signing subject\n");
	return 0;
    }

    char *sigstr = dictionary_get(dict, "sig", 0);
    printf("sig to verify is %s\n", sigstr);

    bstring binsig = bfromcstralloc(strlen(sigstr) / 2, "");
    char *s, *e;
    for (s = sigstr, e = sigstr + strlen(sigstr); s < e; s += 2)
    {
	char n[3];
	n[0] = s[0];
	n[1] = s[1];
	n[2] = 0;
	long int v = strtol(n, 0, 16);
//	printf("n=%s v=%ld %lx\n", n, v, v);
	bconchar(binsig, (char) v);
    }

    unsigned char *sha = SHA1((const unsigned char *) to_sign->data, to_sign->slen, 0);

    bdestroy(to_sign);

    bstring bsubj = bfromcstr(subj);
    bstring pubkey = get_signer_pubkey(bsubj);

    BIO *bio = BIO_new(BIO_s_mem());
    BIO_puts(bio, bdata(pubkey));

    RSA *rsa = PEM_read_bio_RSAPublicKey(bio, 0, 0, 0);

    int rc = RSA_verify(NID_sha1, sha, SHA_DIGEST_LENGTH, binsig->data, binsig->slen, rsa);
    printf("rc=%d\n", rc);

    bdestroy(bsubj);
    bdestroy(binsig);
    bdestroy(pubkey);
    BIO_free(bio);
    RSA_free(rsa);
    dictionary_del(dict);
    EVP_cleanup();
    
    return rc;
}
Beispiel #28
0
RSAKeyImpl::RSAKeyImpl(const std::string& publicKeyFile, 
	const std::string& privateKeyFile, 
	const std::string& privateKeyPassphrase): KeyPairImpl("rsa", KT_RSA_IMPL),
		_pRSA(0)
{
	poco_assert_dbg(_pRSA == 0);

	_pRSA = RSA_new();
	if (!publicKeyFile.empty())
	{
		BIO* bio = BIO_new(BIO_s_file());
		if (!bio) throw Poco::IOException("Cannot create BIO for reading public key", publicKeyFile);
		int rc = BIO_read_filename(bio, publicKeyFile.c_str());
		if (rc)
		{
			RSA* pubKey = PEM_read_bio_RSAPublicKey(bio, &_pRSA, 0, 0);
			if (!pubKey)
			{
				int rc = BIO_reset(bio);
				// BIO_reset() normally returns 1 for success and 0 or -1 for failure. 
				// File BIOs are an exception, they return 0 for success and -1 for failure.
				if (rc != 0) throw Poco::FileException("Failed to load public key", publicKeyFile);
				pubKey = PEM_read_bio_RSA_PUBKEY(bio, &_pRSA, 0, 0);
			}
			BIO_free(bio);
			if (!pubKey)
			{
				freeRSA();
				throw Poco::FileException("Failed to load public key", publicKeyFile);
			}
		}
		else
		{
			freeRSA();
			throw Poco::FileNotFoundException("Public key file", publicKeyFile);
		}
	}

	if (!privateKeyFile.empty())
	{
		BIO* bio = BIO_new(BIO_s_file());
		if (!bio) throw Poco::IOException("Cannot create BIO for reading private key", privateKeyFile);
		int rc = BIO_read_filename(bio, privateKeyFile.c_str());
		if (rc)
		{
			RSA* privKey = 0;
			if (privateKeyPassphrase.empty())
				privKey = PEM_read_bio_RSAPrivateKey(bio, &_pRSA, 0, 0);
			else
				privKey = PEM_read_bio_RSAPrivateKey(bio, &_pRSA, 0, const_cast<char*>(privateKeyPassphrase.c_str()));
			BIO_free(bio);
			if (!privKey)
			{
				freeRSA();
				throw Poco::FileException("Failed to load private key", privateKeyFile);
			}
		}
		else
		{
			freeRSA();
			throw Poco::FileNotFoundException("Private key file", privateKeyFile);
		}
	}
}
	void SecureServer::generateCertificate(const std::string& publicKey, const std::string& privateKey, const std::string& password,
		const long& secsValid, const std::vector<std::pair<std::string,std::string> >& x509Entries,
		const std::string& x509Filename) throw (boost::system::system_error) {
			std::cerr << "generating certificate" << std::endl;
		std::unique_ptr<X509,void (*)(X509*)> x509(X509_new(), &X509_free);
		
		if(ASN1_INTEGER_set(X509_get_serialNumber(x509.get()), std::time(nullptr)) != 1){
			throw_system_error_ssl("Could not set X509 parameters");
		}
		X509_gmtime_adj(X509_get_notBefore(x509.get()), 0);
		X509_gmtime_adj(X509_get_notAfter(x509.get()), secsValid);
		std::unique_ptr<EVP_PKEY,void(*)(EVP_PKEY*)> privKey(EVP_PKEY_new(), &EVP_PKEY_free);
		std::unique_ptr<EVP_PKEY,void(*)(EVP_PKEY*)> pubKey(EVP_PKEY_new(), &EVP_PKEY_free);
		std::unique_ptr<BIO,void (*)(BIO*)> privateBIO(BIO_new_file(privateKey.c_str(), "r"), &BIO_free_all);
		if(!privateBIO){
			throw_system_error_ssl("Could not open "+privateKey+" for reading");
		}
		pem_password_cb* password_cb(nullptr);
		void *password_u(nullptr);
		if(!password.empty()){
			password_cb = &pemPasswordCBFromString;
			password_u = (void*)&password;
		}
		std::unique_ptr<RSA,void(*)(RSA*)> rsa(PEM_read_bio_RSAPrivateKey(privateBIO.get(), nullptr, password_cb, password_u),&RSA_free);
		if(!rsa){
			throw_system_error_ssl("Could not read PEM RSA private key from "+privateKey);
		}
		std::cerr << "read " << privateKey << std::endl;
		if(EVP_PKEY_set1_RSA(privKey.get(), rsa.get()) != 1){
			throw_system_error_ssl("Could not assign EVP_PKEY from RSA private key");
		}
		std::cerr << "assigned EVP_PKEY" << std::endl;
		std::unique_ptr<BIO,void (*)(BIO*)> publicBIO(BIO_new_file(publicKey.c_str(), "r"), &BIO_free_all);
		if(!publicBIO){
			throw_system_error_ssl("Could not open "+publicKey+" for reading");
		}
		RSA *ptr = rsa.get();
		if(PEM_read_bio_RSAPublicKey(publicBIO.get(),&ptr,nullptr,nullptr) == nullptr){
			throw_system_error_ssl("Could not read PEM RSA public key from "+publicKey);
		}
		std::cerr << "read " << publicKey << std::endl;
		if(EVP_PKEY_set1_RSA(pubKey.get(), rsa.get()) != 1){
			throw_system_error_ssl("Could not assign EVP_PKEY from RSA public key");
		}
		
		if(X509_set_pubkey(x509.get(), pubKey.get()) != 1){
			throw_system_error_ssl("Could nost assign X509 public key from EVP_PKEY");
		}
		X509_NAME *name = X509_get_subject_name(x509.get());
		std::cerr << "got subject name" << std::endl;
		for(const std::pair<std::string,std::string>& entry : x509Entries){
			if(X509_NAME_add_entry_by_txt(name, entry.first.c_str(), MBSTRING_ASC, (const unsigned char*)entry.second.c_str(), entry.second.length(), -1, 0) != 1){
				throw_system_error_ssl("Could not add X509 entry /"+entry.first+"/ = \""+entry.second+'"');
			}
			std::cerr << "added entry /" << entry.first << "/ = \"" << entry.second << '"' << std::endl;
		}
		if(X509_set_issuer_name(x509.get(),name) != 1){
			throw_system_error_ssl("Could not set X509 issuer name");
		}
		std::cerr << "set issuer name" << std::endl;
		std::unique_ptr<EVP_MD_CTX,void(*)(EVP_MD_CTX*)> mctx(EVP_MD_CTX_create(),&EVP_MD_CTX_destroy);
// 		EVP_PKEY_CTX *pkctx(nullptr);
		if(EVP_DigestSignInit(mctx.get(),nullptr,EVP_sha256(),nullptr,privKey.get()) != 1){
			throw_system_error_ssl("Could not init EVP Digest Sign");
		}
		std::cerr << "initialized EVP MD CTX" << std::endl;
		if(X509_sign_ctx(x509.get(),mctx.get()) <= 0){
			throw_system_error_ssl("Could not sign certificate");
		}
		std::cerr << "signed" << std::endl;
		std::unique_ptr<BIO,void(*)(BIO*)> x509BIO(BIO_new_file(x509Filename.c_str(),"w"),&BIO_free_all);
		if(PEM_write_bio_X509(x509BIO.get(),x509.get()) != 1){
			throw_system_error_ssl("Could not write X509 certificate");
		}
		std::cerr << "written to " << x509Filename << std::endl;
	}
Beispiel #30
0
void UpdateChecker::unpackUpdate() {
	QByteArray packed;
	if (!outputFile.open(QIODevice::ReadOnly)) {
		LOG(("Update Error: cant read updates file!"));
		return fatalFail();
	}

#ifdef Q_OS_WIN // use Lzma SDK for win
	const int32 hSigLen = 128, hShaLen = 20, hPropsLen = LZMA_PROPS_SIZE, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hPropsLen + hOriginalSizeLen; // header
#else // Q_OS_WIN
	const int32 hSigLen = 128, hShaLen = 20, hPropsLen = 0, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hOriginalSizeLen; // header
#endif // Q_OS_WIN

	QByteArray compressed = outputFile.readAll();
	int32 compressedLen = compressed.size() - hSize;
	if (compressedLen <= 0) {
		LOG(("Update Error: bad compressed size: %1").arg(compressed.size()));
		return fatalFail();
	}
	outputFile.close();

	QString tempDirPath = cWorkingDir() + qsl("tupdates/temp"), readyFilePath = cWorkingDir() + qsl("tupdates/temp/ready");
	psDeleteDir(tempDirPath);

	QDir tempDir(tempDirPath);
	if (tempDir.exists() || QFile(readyFilePath).exists()) {
		LOG(("Update Error: cant clear tupdates/temp dir!"));
		return fatalFail();
	}

	uchar sha1Buffer[20];
	bool goodSha1 = !memcmp(compressed.constData() + hSigLen, hashSha1(compressed.constData() + hSigLen + hShaLen, compressedLen + hPropsLen + hOriginalSizeLen, sha1Buffer), hShaLen);
	if (!goodSha1) {
		LOG(("Update Error: bad SHA1 hash of update file!"));
		return fatalFail();
	}

	RSA *pbKey = PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast<char*>(AppAlphaVersion ? UpdatesPublicAlphaKey : UpdatesPublicKey), -1), 0, 0, 0);
	if (!pbKey) {
		LOG(("Update Error: cant read public rsa key!"));
		return fatalFail();
	}
	if (RSA_verify(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (const uchar*)(compressed.constData()), hSigLen, pbKey) != 1) { // verify signature
		RSA_free(pbKey);
		if (cAlphaVersion() || cBetaVersion()) { // try other public key, if we are in alpha or beta version
			pbKey = PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast<char*>(AppAlphaVersion ? UpdatesPublicKey : UpdatesPublicAlphaKey), -1), 0, 0, 0);
			if (!pbKey) {
				LOG(("Update Error: cant read public rsa key!"));
				return fatalFail();
			}
			if (RSA_verify(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (const uchar*)(compressed.constData()), hSigLen, pbKey) != 1) { // verify signature
				RSA_free(pbKey);
				LOG(("Update Error: bad RSA signature of update file!"));
				return fatalFail();
			}
		} else {
			LOG(("Update Error: bad RSA signature of update file!"));
			return fatalFail();
		}
	}
	RSA_free(pbKey);

	QByteArray uncompressed;

	int32 uncompressedLen;
	memcpy(&uncompressedLen, compressed.constData() + hSigLen + hShaLen + hPropsLen, hOriginalSizeLen);
	uncompressed.resize(uncompressedLen);

	size_t resultLen = uncompressed.size();
#ifdef Q_OS_WIN // use Lzma SDK for win
	SizeT srcLen = compressedLen;
	int uncompressRes = LzmaUncompress((uchar*)uncompressed.data(), &resultLen, (const uchar*)(compressed.constData() + hSize), &srcLen, (const uchar*)(compressed.constData() + hSigLen + hShaLen), LZMA_PROPS_SIZE);
	if (uncompressRes != SZ_OK) {
		LOG(("Update Error: could not uncompress lzma, code: %1").arg(uncompressRes));
		return fatalFail();
	}
#else // Q_OS_WIN
	lzma_stream stream = LZMA_STREAM_INIT;

	lzma_ret ret = lzma_stream_decoder(&stream, UINT64_MAX, LZMA_CONCATENATED);
	if (ret != LZMA_OK) {
		const char *msg;
		switch (ret) {
		case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
		case LZMA_OPTIONS_ERROR: msg = "Specified preset is not supported"; break;
		case LZMA_UNSUPPORTED_CHECK: msg = "Specified integrity check is not supported"; break;
		default: msg = "Unknown error, possibly a bug"; break;
		}
		LOG(("Error initializing the decoder: %1 (error code %2)").arg(msg).arg(ret));
		return fatalFail();
	}

	stream.avail_in = compressedLen;
	stream.next_in = (uint8_t*)(compressed.constData() + hSize);
	stream.avail_out = resultLen;
	stream.next_out = (uint8_t*)uncompressed.data();

	lzma_ret res = lzma_code(&stream, LZMA_FINISH);
	if (stream.avail_in) {
		LOG(("Error in decompression, %1 bytes left in _in of %2 whole.").arg(stream.avail_in).arg(compressedLen));
		return fatalFail();
	} else if (stream.avail_out) {
		LOG(("Error in decompression, %1 bytes free left in _out of %2 whole.").arg(stream.avail_out).arg(resultLen));
		return fatalFail();
	}
	lzma_end(&stream);
	if (res != LZMA_OK && res != LZMA_STREAM_END) {
		const char *msg;
		switch (res) {
		case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
		case LZMA_FORMAT_ERROR: msg = "The input data is not in the .xz format"; break;
		case LZMA_OPTIONS_ERROR: msg = "Unsupported compression options"; break;
		case LZMA_DATA_ERROR: msg = "Compressed file is corrupt"; break;
		case LZMA_BUF_ERROR: msg = "Compressed data is truncated or otherwise corrupt"; break;
		default: msg = "Unknown error, possibly a bug"; break;
		}
		LOG(("Error in decompression: %1 (error code %2)").arg(msg).arg(res));
		return fatalFail();
	}
#endif // Q_OS_WIN

	tempDir.mkdir(tempDir.absolutePath());

	quint32 version;
	{
		QBuffer buffer(&uncompressed);
		buffer.open(QIODevice::ReadOnly);
		QDataStream stream(&buffer);
		stream.setVersion(QDataStream::Qt_5_1);

		stream >> version;
		if (stream.status() != QDataStream::Ok) {
			LOG(("Update Error: cant read version from downloaded stream, status: %1").arg(stream.status()));
			return fatalFail();
		}

		quint64 betaVersion = 0;
		if (version == 0x7FFFFFFF) { // beta version
			stream >> betaVersion;
			if (stream.status() != QDataStream::Ok) {
				LOG(("Update Error: cant read beta version from downloaded stream, status: %1").arg(stream.status()));
				return fatalFail();
			}
			if (!cBetaVersion() || betaVersion <= cBetaVersion()) {
				LOG(("Update Error: downloaded beta version %1 is not greater, than mine %2").arg(betaVersion).arg(cBetaVersion()));
				return fatalFail();
			}
		} else if (int32(version) <= AppVersion) {