int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) { int reason_code, ret = 0; BIO *in; RSA *rsa = NULL; in = BIO_new(BIO_s_file()); if (in == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); goto end; } if (BIO_read_filename(in, file) <= 0) { OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); goto end; } if (type == SSL_FILETYPE_ASN1) { reason_code = ERR_R_ASN1_LIB; rsa = d2i_RSAPrivateKey_bio(in, NULL); } else if (type == SSL_FILETYPE_PEM) { reason_code = ERR_R_PEM_LIB; rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata); } else { OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); goto end; } if (rsa == NULL) { OPENSSL_PUT_ERROR(SSL, reason_code); goto end; } ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); RSA_free(rsa); end: BIO_free(in); return ret; }
int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) { int j, ret = 0; BIO *in; RSA *rsa = NULL; in = BIO_new(BIO_s_file_internal()); if (in == NULL) { SSLerrorx(ERR_R_BUF_LIB); goto end; } if (BIO_read_filename(in, file) <= 0) { SSLerrorx(ERR_R_SYS_LIB); goto end; } if (type == SSL_FILETYPE_ASN1) { j = ERR_R_ASN1_LIB; rsa = d2i_RSAPrivateKey_bio(in, NULL); } else if (type == SSL_FILETYPE_PEM) { j = ERR_R_PEM_LIB; rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata); } else { SSLerrorx(SSL_R_BAD_SSL_FILETYPE); goto end; } if (rsa == NULL) { SSLerrorx(j); goto end; } ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); RSA_free(rsa); end: BIO_free(in); return (ret); }
int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) { int j, ret = 0; BIO *in; RSA *rsa = NULL; in = BIO_new(BIO_s_file()); if (in == NULL) { SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); goto end; } if (BIO_read_filename(in, file) <= 0) { SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); goto end; } if (type == SSL_FILETYPE_ASN1) { j = ERR_R_ASN1_LIB; rsa = d2i_RSAPrivateKey_bio(in, NULL); } else if (type == SSL_FILETYPE_PEM) { j = ERR_R_PEM_LIB; rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ssl->ctx->default_passwd_callback, ssl-> ctx->default_passwd_callback_userdata); } else { SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); goto end; } if (rsa == NULL) { SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, j); goto end; } ret = SSL_use_RSAPrivateKey(ssl, rsa); RSA_free(rsa); end: BIO_free(in); return (ret); }
uint8_t *rsa_apply(uint8_t *input, int inlen, int *outlen, int mode) { static RSA *rsa = NULL; if (!rsa) { BIO *bmem = BIO_new_mem_buf(super_secret_key, -1); rsa = PEM_read_bio_RSAPrivateKey(bmem, NULL, NULL, NULL); BIO_free(bmem); } uint8_t *out = malloc(RSA_size(rsa)); switch (mode) { case RSA_MODE_AUTH: *outlen = RSA_private_encrypt(inlen, input, out, rsa, RSA_PKCS1_PADDING); break; case RSA_MODE_KEY: *outlen = RSA_private_decrypt(inlen, input, out, rsa, RSA_PKCS1_OAEP_PADDING); break; default: die("bad rsa mode"); } return out; }
int amqp_ssl_socket_set_key_buffer(amqp_socket_t *base, const char *cert, const void *key, size_t n) { int status = AMQP_STATUS_OK; BIO *buf = NULL; RSA *rsa = NULL; struct amqp_ssl_socket_t *self; if (base->klass != &amqp_ssl_socket_class) { amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); } self = (struct amqp_ssl_socket_t *)base; status = SSL_CTX_use_certificate_chain_file(self->ctx, cert); if (1 != status) { return AMQP_STATUS_SSL_ERROR; } buf = BIO_new_mem_buf((void *)key, n); if (!buf) { goto error; } rsa = PEM_read_bio_RSAPrivateKey(buf, NULL, password_cb, NULL); if (!rsa) { goto error; } status = SSL_CTX_use_RSAPrivateKey(self->ctx, rsa); if (1 != status) { goto error; } exit: BIO_vfree(buf); RSA_free(rsa); return status; error: status = AMQP_STATUS_SSL_ERROR; goto exit; }
RSA* createRSA(unsigned char* key, int is_public){ RSA* rsa = NULL; BIO* keybio; keybio = BIO_new_mem_buf(key, -1); if(keybio == NULL){ printf("Failed to create key BIO\n"); return 0; } if(is_public){ rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa, NULL, NULL); } else{ rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL); } if(rsa == NULL){ printf("Failed to create RSA\n"); } BIO_free(keybio); return rsa; }
/* * private key decrypt */ char* rsa_decrypt_private(unsigned char *enc,int enc_len,char* private_key_str,int p_len,int *dec_len) { int rsa_private_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_RSAPrivateKey(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_private_decrypt(rsa_len,(unsigned char *)enc,(unsigned char*)p_de,rsa,RSA_PKCS1_PADDING); 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; }
/** * 功能描述:RSA解密 * @param pData:原始数据 * @param ilen: 原始数据长度 * @param pEncodeData: 加密后数据 * @return -1: 失败, 其他: 加密数据长度 **/ int RSADecrypt(const char* pData , int iLen, char** pDecodeData) { char chPrivateKey[] = "-----BEGIN RSA PRIVATE KEY-----\n" "MIICXQIBAAKBgQCb/vAGucNg3OJyBV6/aWEd7IK946GYnOT089mDzNY2zDBB9hPW\n" "wdSUYOTbDROlc3Gd4eOudeQqlnAgHB7zqwVGqWuGvbqHWSSPpp6pMilpVVz9SMbL\n" "/1BgfhK+dKWIDYHJDRJFpBLFUpe0vq8n+8Mdgp1zNPH3cR+rWK8zI5xF5wIDAQAB\n" "AoGBAJesW+KeMbp3afElCYegxV2b/U72CcPiILeOdRoySsHC7NTll0qC8ddHEp1t\n" "bIG86mZxILgbRjqmROTjkrCmwxv5tHT1LRHz139BPQHbOx+Dx5Q/D9wUzGKSr/Df\n" "lUsORpqmQjVsgLtCzIZShXr/O2rf8FU6zbtI3f6UQK1wMcxRAkEAydNkWUvSkxC2\n" "40fA8+6mYFXEWgJpXLcaMX+CqMmE+h/xwDJ7qB0dbqdPA64Pq2jgLAFWlSxF4QWk\n" "Kp19gaoR/wJBAMXeT0LqCg7RG365KsvXzJVf9gzxN1X0ahhKBSoAS66UgpyVDGcl\n" "b+NchCepqev6Li/U+Zteg/UrTTNBN8S3fBkCQHyGhX/jHIXI5k7NUuwu71C5GnE+\n" "06t0/iBUQFXMINQDKbIgc9OCQ0qmyEXI+7oS912vZbCcpHD2fhgdG/cI7BkCQQCK\n" "gIxWuGAF8xUd5RsxyIJp5NvkP0yOnCFPkzB+L+rJ7yZl2GbwJGJncbEH2lkY1uxR\n" "ivCVctlHWeIWCIay6gSxAkAF19y/R2dMkop5Pl0UkGCzY4Bgqqmnxs+I+o2Z4EwE\n" "xc/l6vH6yP3DmelxC4abDk/N7bgaU99lQ2iwN+RpHUpP" "\n-----END RSA PRIVATE KEY-----\n"; BIO *bio = BIO_new_mem_buf(chPrivateKey, -1); if (!bio) { return -1; } RSA* rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL); if (!rsa) { return -1; } int nLen = RSA_size(rsa); char* pDecode = (char*)malloc(nLen + 1); memset(pDecode, 0, nLen+1); int rc = RSA_private_decrypt(nLen ,(unsigned char *)pData,(unsigned char*)pDecode,rsa,RSA_PKCS1_PADDING); *pDecodeData = pDecode; RSA_free(rsa); CRYPTO_cleanup_all_ex_data(); return rc; }
rsa(const std::string& key) { if (key.size() > 26 && std::equal(key.begin(), key.begin() + 26, "-----BEGIN PUBLIC KEY-----")) { this->is_pub = true; } else if (key.size() > 31 && std::equal(key.begin(), key.begin() + 31, "-----BEGIN RSA PRIVATE KEY-----")) { this->is_pub = false; } else { throw std::invalid_argument("invalid argument"); } auto bio_handle = std::shared_ptr<BIO>(BIO_new_mem_buf(const_cast<char*>(key.data()), key.size()), BIO_free); if (bio_handle) { if (this->is_pub) { this->rsa_handle = std::shared_ptr<RSA>(PEM_read_bio_RSA_PUBKEY(bio_handle.get(), nullptr, nullptr, nullptr), RSA_free); } else { this->rsa_handle = std::shared_ptr<RSA>(PEM_read_bio_RSAPrivateKey(bio_handle.get(), nullptr, nullptr, nullptr), RSA_free); } } if (!this->rsa_handle) { throw std::invalid_argument("invalid argument"); } }
static CURLcode ssl_ctx_callback(CURL *curl, void *ssl_ctx, void *userptr) { CURLcode result; if ( (curl == NULL) || (ssl_ctx == NULL) || (userptr == NULL) ) { LogError("unexpected parameter CURL *curl=%p, void *ssl_ctx=%p, void *userptr=%p", curl, ssl_ctx, userptr); result = CURLE_SSL_CERTPROBLEM; } else { HTTP_HANDLE_DATA *httpHandleData = (HTTP_HANDLE_DATA *)userptr; BIO *bio_certificate; bio_certificate = BIO_new_mem_buf(httpHandleData->x509certificate, -1); if (bio_certificate == NULL) { LogError("cannot create BIO *bio_certificate"); result = CURLE_OUT_OF_MEMORY; } else { X509 *cert = PEM_read_bio_X509(bio_certificate, NULL, 0, NULL); if (cert == NULL) { LogError("cannot create X509 *cert"); result = CURLE_SSL_CERTPROBLEM; } else { BIO *bio_privatekey; bio_privatekey = BIO_new_mem_buf(httpHandleData->x509privatekey, -1); if (bio_privatekey == NULL) { LogError("cannot create BIO *bio_privatekey;"); result = CURLE_OUT_OF_MEMORY; } else { RSA* privatekey = PEM_read_bio_RSAPrivateKey(bio_privatekey, NULL, 0, NULL); if (privatekey == NULL) { LogError("cannot create RSA* privatekey"); result = CURLE_SSL_CERTPROBLEM; /*there's no better code in CURL about not being able to load a private key*/ } else { if (SSL_CTX_use_certificate((SSL_CTX*)ssl_ctx, cert) != 1) { LogError("cannot SSL_CTX_use_certificate"); result = CURLE_SSL_CERTPROBLEM; /*there's no better code in CURL about not being able to SSL_CTX_use_certificate*/ } else { if (SSL_CTX_use_RSAPrivateKey(ssl_ctx, privatekey) != 1) { LogError("cannot SSL_CTX_use_RSAPrivateKey"); result = CURLE_SSL_CERTPROBLEM; /*there's no better code in CURL about not being able to put a private key in an SSL context*/ } else { result = CURLE_OK; } } RSA_free(privatekey); } BIO_free(bio_privatekey); } X509_free(cert); } BIO_free(bio_certificate); } } return result; }
/* * js private key decrypt */ char * js_private_decrypt(const char *cipher_text,int length, char *private_key) { RSA *rsa_privateKey = NULL; int rsa_private_len; int i; // private_key = rsa_key_seliaze(private_key_str); //BIO* p_bio = BIO_new_mem_buf(PRIVATE_KEY, -1); BIO* p_bio = BIO_new_mem_buf(private_key, -1); rsa_privateKey = PEM_read_bio_RSAPrivateKey(p_bio, NULL, 0, NULL); // if ( rsa_privateKey == NULL ) { printf("RSA is NULL\n"); return NULL; } //printf("Cipher text: %s\n", cipher_text); rsa_private_len = RSA_size(rsa_privateKey); // printf("RSA private length: %d\n", rsa_private_len); size_t crypt_len = 0; //unsigned char *crypt = base64_decode(cipher_text, strlen(cipher_text), &crypt_len); char *crypt = (char *)cipher_text; crypt_len = length; // printf("Decoded cipher: %s\nCrypt length: %ld\n", crypt, crypt_len); // If no static, it will cause "address of stack memory associated with local variable ...", which mean the variable will released from memory after the end of this function char *plain_char = malloc(crypt_len); memset(plain_char,0,crypt_len); // initialize strcpy(plain_char, ""); char *err = NULL; for ( i = 0; i < crypt_len; i += rsa_private_len) { unsigned char *crypt_chunk = malloc(rsa_private_len + 1); memset(crypt_chunk,0,rsa_private_len + 1); memcpy(&crypt_chunk[0], &crypt[i], rsa_private_len); // printf("Crypt chunk: %s\n", crypt_chunk); unsigned char *result_chunk = malloc(crypt_len + 1); memset(result_chunk,0,crypt_len + 1); int result_length = RSA_private_decrypt(rsa_private_len, crypt_chunk, result_chunk, rsa_privateKey, RSA_PKCS1_PADDING); // chunk length should be the size of privatekey (in bytes) minus 11 (overhead during encryption) // printf("Result chunk: %s\nChunk length: %d\n", result_chunk, result_length); free(crypt_chunk); // this is to omit the dummy character behind // i.e. Result chunk: ABC-1234567-201308101427371250-abcdefghijklmnopqrstuv\240Z // Chunk length: 53 // New chunk: ABC-1234567-201308101427371250-abcdefghijklmnopqrstuv // // by copying the chunk to a temporary variable with an extra length (i.e. in this case is 54) // and then set the last character of temporary variable to NULL char tmp_result[result_length + 1]; memcpy(tmp_result, result_chunk, result_length); tmp_result[result_length] = '\0'; // printf("New chunk: %s\n", tmp_result); free(result_chunk); if (result_length == -1) { ERR_load_CRYPTO_strings(); fprintf(stderr, "Error %s\n", ERR_error_string(ERR_get_error(), err)); fprintf(stderr, "Error %s\n", err); } strcat(plain_char, tmp_result); } RSA_free(rsa_privateKey); //free(crypt); // printf("Final result: %s\n", plain_char); return plain_char; }
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; }
/* * Sign an assertion. */ static char * keynote_sign_assertion(struct assertion *as, char *sigalg, void *key, int keyalg, int verifyflag) { int slen, i, hashlen = 0, hashtype, alg, encoding, internalenc; unsigned char *sig = NULL, *finalbuf = NULL; unsigned char res2[LARGEST_HASH_SIZE], *sbuf = NULL; BIO *biokey = NULL; DSA *dsa = NULL; RSA *rsa = NULL; SHA_CTX shscontext; MD5_CTX md5context; int len; if (as->as_signature_string_s == NULL || as->as_startofsignature == NULL || as->as_allbutsignature == NULL || as->as_allbutsignature - as->as_startofsignature <= 0 || as->as_authorizer == NULL || key == NULL || as->as_signeralgorithm == KEYNOTE_ALGORITHM_NONE) { keynote_errno = ERROR_SYNTAX; return NULL; } alg = keynote_get_sig_algorithm(sigalg, &hashtype, &encoding, &internalenc); if (((alg != as->as_signeralgorithm) && !((alg == KEYNOTE_ALGORITHM_RSA) && (as->as_signeralgorithm == KEYNOTE_ALGORITHM_X509)) && !((alg == KEYNOTE_ALGORITHM_X509) && (as->as_signeralgorithm == KEYNOTE_ALGORITHM_RSA))) || ((alg != keyalg) && !((alg == KEYNOTE_ALGORITHM_RSA) && (keyalg == KEYNOTE_ALGORITHM_X509)) && !((alg == KEYNOTE_ALGORITHM_X509) && (keyalg == KEYNOTE_ALGORITHM_RSA)))) { keynote_errno = ERROR_SYNTAX; return NULL; } sig = strchr(sigalg, ':'); if (sig == NULL) { keynote_errno = ERROR_SYNTAX; return NULL; } sig++; switch (hashtype) { case KEYNOTE_HASH_SHA1: hashlen = 20; memset(res2, 0, hashlen); SHA1_Init(&shscontext); SHA1_Update(&shscontext, as->as_startofsignature, as->as_allbutsignature - as->as_startofsignature); SHA1_Update(&shscontext, sigalg, (char *) sig - sigalg); SHA1_Final(res2, &shscontext); break; case KEYNOTE_HASH_MD5: hashlen = 16; memset(res2, 0, hashlen); MD5_Init(&md5context); MD5_Update(&md5context, as->as_startofsignature, as->as_allbutsignature - as->as_startofsignature); MD5_Update(&md5context, sigalg, (char *) sig - sigalg); MD5_Final(res2, &md5context); break; case KEYNOTE_HASH_NONE: break; } if ((alg == KEYNOTE_ALGORITHM_DSA) && (hashtype == KEYNOTE_HASH_SHA1) && (internalenc == INTERNAL_ENC_ASN1) && ((encoding == ENCODING_HEX) || (encoding == ENCODING_BASE64))) { dsa = (DSA *) key; sbuf = calloc(DSA_size(dsa), sizeof(unsigned char)); if (sbuf == NULL) { keynote_errno = ERROR_MEMORY; return NULL; } if (DSA_sign(0, res2, hashlen, sbuf, &slen, dsa) <= 0) { free(sbuf); keynote_errno = ERROR_SYNTAX; return NULL; } } else if ((alg == KEYNOTE_ALGORITHM_RSA) && ((hashtype == KEYNOTE_HASH_SHA1) || (hashtype == KEYNOTE_HASH_MD5)) && (internalenc == INTERNAL_ENC_PKCS1) && ((encoding == ENCODING_HEX) || (encoding == ENCODING_BASE64))) { rsa = (RSA *) key; sbuf = calloc(RSA_size(rsa), sizeof(unsigned char)); if (sbuf == NULL) { keynote_errno = ERROR_MEMORY; return NULL; } if (RSA_sign_ASN1_OCTET_STRING(RSA_PKCS1_PADDING, res2, hashlen, sbuf, &slen, rsa) <= 0) { free(sbuf); keynote_errno = ERROR_SYNTAX; return NULL; } } else if ((alg == KEYNOTE_ALGORITHM_X509) && (hashtype == KEYNOTE_HASH_SHA1) && (internalenc == INTERNAL_ENC_ASN1)) { if ((biokey = BIO_new(BIO_s_mem())) == NULL) { keynote_errno = ERROR_SYNTAX; return NULL; } if (BIO_write(biokey, key, strlen(key) + 1) <= 0) { BIO_free(biokey); keynote_errno = ERROR_SYNTAX; return NULL; } /* RSA-specific */ rsa = (RSA *) PEM_read_bio_RSAPrivateKey(biokey, NULL, NULL, NULL); if (rsa == NULL) { BIO_free(biokey); keynote_errno = ERROR_SYNTAX; return NULL; } sbuf = calloc(RSA_size(rsa), sizeof(char)); if (sbuf == NULL) { BIO_free(biokey); RSA_free(rsa); keynote_errno = ERROR_MEMORY; return NULL; } if (RSA_sign(NID_shaWithRSAEncryption, res2, hashlen, sbuf, &slen, rsa) <= 0) { BIO_free(biokey); RSA_free(rsa); free(sbuf); keynote_errno = ERROR_SIGN_FAILURE; return NULL; } BIO_free(biokey); RSA_free(rsa); } else /* Other algorithms here */ { keynote_errno = ERROR_SYNTAX; return NULL; } /* ASCII encoding */ switch (encoding) { case ENCODING_HEX: i = kn_encode_hex(sbuf, (char **) &finalbuf, slen); free(sbuf); if (i != 0) return NULL; break; case ENCODING_BASE64: finalbuf = calloc(2 * slen, sizeof(unsigned char)); if (finalbuf == NULL) { keynote_errno = ERROR_MEMORY; free(sbuf); return NULL; } if ((slen = kn_encode_base64(sbuf, slen, finalbuf, 2 * slen)) == -1) { free(sbuf); return NULL; } break; default: free(sbuf); keynote_errno = ERROR_SYNTAX; return NULL; } /* Replace as->as_signature */ len = strlen(sigalg) + strlen(finalbuf) + 1; as->as_signature = calloc(len, sizeof(char)); if (as->as_signature == NULL) { free(finalbuf); keynote_errno = ERROR_MEMORY; return NULL; } /* Concatenate algorithm name and signature value */ snprintf(as->as_signature, len, "%s%s", sigalg, finalbuf); free(finalbuf); finalbuf = as->as_signature; /* Verify the newly-created signature if requested */ if (verifyflag) { /* Do the signature verification */ if (keynote_sigverify_assertion(as) != SIGRESULT_TRUE) { as->as_signature = NULL; free(finalbuf); if (keynote_errno == 0) keynote_errno = ERROR_SYNTAX; return NULL; } as->as_signature = NULL; } else as->as_signature = NULL; /* Everything ok */ return (char *) finalbuf; }
/* * js private key encrypt */ char * js_private_encrypt(const char *plain_text,int * encode_len ,char *private_key) { RSA *rsa_privateKey = NULL; int rsa_private_len; int i; // private_key = rsa_key_seliaze(private_key_str); //BIO* p_bio = BIO_new_mem_buf(PRIVATE_KEY, -1); BIO* p_bio = BIO_new_mem_buf(private_key, -1); rsa_privateKey = PEM_read_bio_RSAPrivateKey(p_bio, NULL, 0, NULL); // if ( rsa_privateKey == NULL ) { printf("RSA is NULL\n"); return NULL; } rsa_private_len = RSA_size(rsa_privateKey); // printf("RSA private length: %d\n", rsa_private_len); // 11 bytes is overhead required for encryption int chunk_length = rsa_private_len - 11; // plain text length int plain_char_len = (int)strlen(plain_text); // calculate the number of chunks int num_of_chunks = (int)(strlen(plain_text) / chunk_length) + 1; int total_cipher_length = 0; // the output size is (total number of chunks) x (the key length) int encrypted_size = (num_of_chunks * rsa_private_len); unsigned char *cipher_data = malloc(encrypted_size + 1); char *err = NULL; for ( i = 0; i < plain_char_len; i += chunk_length) { // get the remaining character count from the plain text int remaining_char_count = plain_char_len - i; // this len is the number of characters to encrypt, thus take the minimum between the chunk count & the remaining characters // this must less than rsa_private_len - 11 int len = JSMIN(remaining_char_count, chunk_length); unsigned char *plain_chunk = malloc(len + 1); memset(plain_chunk,0,len + 1); // take out chunk of plain text memcpy(&plain_chunk[0], &plain_text[i], len); // printf("Plain chunk: %s\n", plain_chunk); unsigned char *result_chunk = malloc(rsa_private_len + 1); memset(result_chunk,0,rsa_private_len + 1); int result_length = RSA_private_encrypt(len, plain_chunk, result_chunk, rsa_privateKey, RSA_PKCS1_PADDING); // RSA_NO_PADDING RSA_PKCS1_PADDING // printf("Encrypted Result chunk: %s\nEncrypted Chunk length: %d\n", result_chunk, result_length); free(plain_chunk); if (result_length == -1) { ERR_load_CRYPTO_strings(); fprintf(stderr, "Error %s\n", ERR_error_string(ERR_get_error(), err)); fprintf(stderr, "Error %s\n", err); } memcpy(&cipher_data[total_cipher_length], &result_chunk[0], result_length); total_cipher_length += result_length; free(result_chunk); } //printf("Total cipher length: %d\n", total_cipher_length); RSA_free(rsa_privateKey); // size_t total_len = 0; // char *encrypted = base64_encode(cipher_data, encrypted_size, &total_len); // printf("Final result: %s\n Final result length: %zu\n", encrypted, total_len); *encode_len = encrypted_size; //free(cipher_data); return cipher_data; }
/* * verify_private_key - reread private key and verify against inmem key */ int verify_private_key(void) { BIO *file; RSA *key; RSA *mkey; /* If the rsa_private_key directive isn't found, error out. */ if(ServerInfo.rsa_private_key == NULL) { ilog(L_NOTICE, "rsa_private_key in serverinfo{} is not defined."); return (-1); } /* If rsa_private_key_file isn't available, error out. */ if(ServerInfo.rsa_private_key_file == NULL) { ilog(L_NOTICE, "Internal error: rsa_private_key_file isn't defined."); return (-1); } file = BIO_new_file(ServerInfo.rsa_private_key_file, "r"); /* * If BIO_new_file returned NULL (according to OpenSSL docs), then * an error occurred. */ if(file == NULL) { ilog(L_NOTICE, "Failed to open private key file - can't validate it"); return (-1); } /* * jdc -- Let's do this a little differently. According to the * OpenSSL documentation, you need to METHOD_free(key) before * assigning it. Don't believe me? Check out the following * URL: http://www.openssl.org/docs/crypto/pem.html#BUGS * P.S. -- I have no idea why the key= assignment has to be typecasted. * For some reason the system thinks PEM_read_bio_RSAPrivateKey * is returning an int, not a RSA *. * androsyn -- Thats because you didn't have a prototype and including * pem.h breaks things for some reason.. */ key = (RSA *) PEM_read_bio_RSAPrivateKey(file, NULL, 0, NULL); if(key == NULL) { ilog(L_NOTICE, "PEM_read_bio_RSAPrivateKey() failed; possibly not RSA?"); report_crypto_errors(); return (-1); } BIO_set_close(file, BIO_CLOSE); BIO_free(file); mkey = ServerInfo.rsa_private_key; /* * Compare the in-memory key to the key we just loaded above. If * any of the portions don't match, then logically we have a different * in-memory key vs. the one we just loaded. This is bad, mmmkay? */ if(mkey->pad != key->pad) ilog(L_CRIT, "Private key corrupted: pad %i != pad %i", mkey->pad, key->pad); if(mkey->version != key->version) ilog(L_CRIT, "Private key corrupted: version %lu != version %lu", (unsigned long) mkey->version, (unsigned long) key->version); if(BN_cmp(mkey->n, key->n)) ilog(L_CRIT, "Private key corrupted: n differs"); if(BN_cmp(mkey->e, key->e)) ilog(L_CRIT, "Private key corrupted: e differs"); if(BN_cmp(mkey->d, key->d)) ilog(L_CRIT, "Private key corrupted: d differs"); if(BN_cmp(mkey->p, key->p)) ilog(L_CRIT, "Private key corrupted: p differs"); if(BN_cmp(mkey->q, key->q)) ilog(L_CRIT, "Private key corrupted: q differs"); if(BN_cmp(mkey->dmp1, key->dmp1)) ilog(L_CRIT, "Private key corrupted: dmp1 differs"); if(BN_cmp(mkey->dmq1, key->dmq1)) ilog(L_CRIT, "Private key corrupted: dmq1 differs"); if(BN_cmp(mkey->iqmp, key->iqmp)) ilog(L_CRIT, "Private key corrupted: iqmp differs"); RSA_free(key); return (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); } } }
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; }
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; }
rdpRsaKey* key_new(const char* keyfile) { BIO* bio = NULL; FILE* fp = NULL; RSA* rsa = NULL; int length; BYTE* buffer = NULL; rdpRsaKey* key = NULL; key = (rdpRsaKey*) calloc(1, sizeof(rdpRsaKey)); if (!key) return NULL; fp = fopen(keyfile, "r+b"); if (!fp) { WLog_ERR(TAG, "unable to open RSA key file %s: %s.", keyfile, strerror(errno)); goto out_free; } fseek(fp, 0, SEEK_END); length = ftell(fp); fseek(fp, 0, SEEK_SET); buffer = (BYTE*) malloc(length); if (!buffer) goto out_free; fread((void*) buffer, length, 1, fp); fclose(fp); bio = BIO_new_mem_buf((void*) buffer, length); if (!bio) goto out_free; rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL); BIO_free(bio); free(buffer); buffer = NULL; if (!rsa) { WLog_ERR(TAG, "unable to load RSA key from %s: %s.", keyfile, strerror(errno)); goto out_free; } switch (RSA_check_key(rsa)) { case 0: WLog_ERR(TAG, "invalid RSA key in %s", keyfile); goto out_free_rsa; case 1: /* Valid key. */ break; default: WLog_ERR(TAG, "unexpected error when checking RSA key from %s: %s.", keyfile, strerror(errno)); goto out_free_rsa; } if (BN_num_bytes(rsa->e) > 4) { WLog_ERR(TAG, "RSA public exponent too large in %s", keyfile); goto out_free_rsa; } key->ModulusLength = BN_num_bytes(rsa->n); key->Modulus = (BYTE*) malloc(key->ModulusLength); if (!key->Modulus) goto out_free_rsa; BN_bn2bin(rsa->n, key->Modulus); crypto_reverse(key->Modulus, key->ModulusLength); key->PrivateExponentLength = BN_num_bytes(rsa->d); key->PrivateExponent = (BYTE*) malloc(key->PrivateExponentLength); if (!key->PrivateExponent) goto out_free_modulus; BN_bn2bin(rsa->d, key->PrivateExponent); crypto_reverse(key->PrivateExponent, key->PrivateExponentLength); memset(key->exponent, 0, sizeof(key->exponent)); BN_bn2bin(rsa->e, key->exponent + sizeof(key->exponent) - BN_num_bytes(rsa->e)); crypto_reverse(key->exponent, sizeof(key->exponent)); RSA_free(rsa); return key; out_free_modulus: free(key->Modulus); out_free_rsa: RSA_free(rsa); out_free: if (fp) fclose(fp); if (buffer) free(buffer); free(key); return NULL; }
char* sign_and_encryptFromFiles(const char *data, char *keyFile, char *certFile, char *ppCertFile, int verbose) /* sign and encrypt button data for safe delivery to paypal, use keys/certs in specified filenames. Free return value with free(). */ { ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); /* Load PayPal cert */ BIO *bio=BIO_new_file(ppCertFile,"rt"); if (!bio) { fprintf(stderr,"Error loading file: %s\n", ppCertFile);fflush(stderr); return NULL; } X509 *ppX509=PEM_read_bio_X509(bio,NULL,NULL,NULL); if (!ppX509) { fprintf(stderr,"Error bio_reading PayPal certificate from %s\n", ppCertFile);fflush(stderr); return NULL; } BIO_free(bio); /* Load Public cert */ bio=BIO_new_file(certFile,"rt"); if (!bio) { fprintf(stderr,"Error loading file: %s\n", certFile);fflush(stderr); return NULL; } X509 *x509=PEM_read_bio_X509(bio,NULL,NULL,NULL); if (!x509) { fprintf(stderr,"Error bio_reading Public certificate from %s\n", certFile);fflush(stderr); return NULL; } BIO_free(bio); /* Load Private key */ bio=BIO_new_file(keyFile,"rt"); if (!bio) { fprintf(stderr,"Error loading file: %s\n", keyFile);fflush(stderr); return NULL; } RSA *rsa=PEM_read_bio_RSAPrivateKey(bio,NULL,NULL,NULL); if (!rsa) { fprintf(stderr,"Error bio_reading RSA key from %s\n", keyFile);fflush(stderr); return NULL; } BIO_free(bio); return sign_and_encrypt(data,rsa,x509,ppX509,verbose); }
static int openssl_ssl_ctx_set_tmp(lua_State *L) { SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); static const char* which[] = { "dh", "rsa", "ecdh", NULL }; int nwhich = luaL_checkoption(L, 2, NULL, which); int ret = 0; if (lua_isfunction(L, 3)) { lua_pushvalue(L, 3); ret = 1; switch (nwhich) { case 0: openssl_setvalue(L, ctx, "tmp_dh_callback"); SSL_CTX_set_tmp_dh_callback(ctx, tmp_dh_callback); break; case 1: openssl_setvalue(L, ctx, "tmp_rsa_callback"); SSL_CTX_set_tmp_rsa_callback(ctx, tmp_rsa_callback); break; case 2: { luaL_argcheck(L, lua_isstring(L, 4), 4, "must supply curve name"); openssl_setvalue(L, ctx, "tmp_ecdh_callback"); SSL_CTX_set_tmp_ecdh_callback(ctx, tmp_ecdh_callback); lua_pushvalue(L, 4); openssl_setvalue(L, ctx, "curve"); } break; } } else if (lua_isstring(L, 3)) { BIO* bio = load_bio_object(L, 3); switch (nwhich) { case 0: { DH* dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); if (dh) ret = SSL_CTX_set_tmp_dh(ctx, dh); else luaL_error(L, "generate new tmp dh fail"); } break; case 1: { RSA* rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL); if (rsa) ret = SSL_CTX_set_tmp_rsa(ctx, rsa); else luaL_error(L, "generate new tmp rsa fail"); } break; case 2: { int nid = NID_undef; EC_KEY* ec = PEM_read_bio_ECPrivateKey(bio, NULL, NULL, NULL); if (ec == NULL) { nid = OBJ_txt2nid(lua_tostring(L, 3)); if (nid != NID_undef) ec = EC_KEY_new_by_curve_name(nid); } if (ec) ret = SSL_CTX_set_tmp_ecdh(ctx, ec); else luaL_error(L, "generate new tmp ec_key fail"); } break; } BIO_free(bio); } else if (lua_isuserdata(L, 3)) { luaL_argerror(L, 3, "userdata arg NYI"); } else luaL_argerror(L, 3, "should be tmp key callback function or pem string or key object"); return openssl_pushresult(L, ret); }
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); if (!pubKey) { int rc = BIO_seek(bio, 0); 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); } } }
idevice_error_t idevice_connection_enable_ssl(idevice_connection_t connection) { if (!connection || connection->ssl_data) return IDEVICE_E_INVALID_ARG; idevice_error_t ret = IDEVICE_E_SSL_ERROR; uint32_t return_me = 0; plist_t pair_record = NULL; userpref_read_pair_record(connection->udid, &pair_record); if (!pair_record) { debug_info("ERROR: Failed enabling SSL. Unable to read pair record for udid %s.", connection->udid); return ret; } #ifdef HAVE_OPENSSL key_data_t root_cert = { NULL, 0 }; key_data_t root_privkey = { NULL, 0 }; pair_record_import_crt_with_name(pair_record, USERPREF_ROOT_CERTIFICATE_KEY, &root_cert); pair_record_import_key_with_name(pair_record, USERPREF_ROOT_PRIVATE_KEY_KEY, &root_privkey); if (pair_record) plist_free(pair_record); /* Set up OpenSSL */ if (openssl_init_done == 0) { SSL_library_init(); openssl_init_done = 1; } BIO *ssl_bio = BIO_new(BIO_s_socket()); if (!ssl_bio) { debug_info("ERROR: Could not create SSL bio."); return ret; } BIO_set_fd(ssl_bio, (int)(long)connection->data, BIO_NOCLOSE); //SSL_CTX *ssl_ctx = SSL_CTX_new(SSLv3_method()); SSL_CTX *ssl_ctx = SSL_CTX_new(SSLv3_client_method()); if (ssl_ctx == NULL) { debug_info("ERROR: Could not create SSL context."); BIO_free(ssl_bio); return ret; } BIO* membp; X509* rootCert = NULL; membp = BIO_new_mem_buf(root_cert.data, root_cert.size); PEM_read_bio_X509(membp, &rootCert, NULL, NULL); BIO_free(membp); if (SSL_CTX_use_certificate(ssl_ctx, rootCert) != 1) { debug_info("WARNING: Could not load RootCertificate"); } X509_free(rootCert); free(root_cert.data); RSA* rootPrivKey = NULL; membp = BIO_new_mem_buf(root_privkey.data, root_privkey.size); PEM_read_bio_RSAPrivateKey(membp, &rootPrivKey, NULL, NULL); BIO_free(membp); if (SSL_CTX_use_RSAPrivateKey(ssl_ctx, rootPrivKey) != 1) { debug_info("WARNING: Could not load RootPrivateKey"); } RSA_free(rootPrivKey); free(root_privkey.data); SSL *ssl = SSL_new(ssl_ctx); if (!ssl) { debug_info("ERROR: Could not create SSL object"); BIO_free(ssl_bio); SSL_CTX_free(ssl_ctx); return ret; } SSL_set_connect_state(ssl); SSL_set_verify(ssl, 0, ssl_verify_callback); SSL_set_bio(ssl, ssl_bio, ssl_bio); return_me = SSL_do_handshake(ssl); if (return_me != 1) { debug_info("ERROR in SSL_do_handshake: %s", ssl_error_to_string(SSL_get_error(ssl, return_me))); SSL_free(ssl); SSL_CTX_free(ssl_ctx); } else { ssl_data_t ssl_data_loc = (ssl_data_t)malloc(sizeof(struct ssl_data_private)); ssl_data_loc->session = ssl; ssl_data_loc->ctx = ssl_ctx; connection->ssl_data = ssl_data_loc; ret = IDEVICE_E_SUCCESS; debug_info("SSL mode enabled, cipher: %s", SSL_get_cipher(ssl)); } /* required for proper multi-thread clean up to prevent leaks */ #ifdef HAVE_ERR_REMOVE_THREAD_STATE ERR_remove_thread_state(NULL); #else ERR_remove_state(0); #endif #else ssl_data_t ssl_data_loc = (ssl_data_t)malloc(sizeof(struct ssl_data_private)); /* Set up GnuTLS... */ debug_info("enabling SSL mode"); errno = 0; gnutls_certificate_allocate_credentials(&ssl_data_loc->certificate); gnutls_certificate_client_set_retrieve_function(ssl_data_loc->certificate, internal_cert_callback); gnutls_init(&ssl_data_loc->session, GNUTLS_CLIENT); gnutls_priority_set_direct(ssl_data_loc->session, "NONE:+VERS-SSL3.0:+ANON-DH:+RSA:+AES-128-CBC:+AES-256-CBC:+SHA1:+MD5:+COMP-NULL", NULL); gnutls_credentials_set(ssl_data_loc->session, GNUTLS_CRD_CERTIFICATE, ssl_data_loc->certificate); gnutls_session_set_ptr(ssl_data_loc->session, ssl_data_loc); gnutls_x509_crt_init(&ssl_data_loc->root_cert); gnutls_x509_crt_init(&ssl_data_loc->host_cert); gnutls_x509_privkey_init(&ssl_data_loc->root_privkey); gnutls_x509_privkey_init(&ssl_data_loc->host_privkey); pair_record_import_crt_with_name(pair_record, USERPREF_ROOT_CERTIFICATE_KEY, ssl_data_loc->root_cert); pair_record_import_crt_with_name(pair_record, USERPREF_HOST_CERTIFICATE_KEY, ssl_data_loc->host_cert); pair_record_import_key_with_name(pair_record, USERPREF_ROOT_PRIVATE_KEY_KEY, ssl_data_loc->root_privkey); pair_record_import_key_with_name(pair_record, USERPREF_HOST_PRIVATE_KEY_KEY, ssl_data_loc->host_privkey); if (pair_record) plist_free(pair_record); debug_info("GnuTLS step 1..."); gnutls_transport_set_ptr(ssl_data_loc->session, (gnutls_transport_ptr_t)connection); debug_info("GnuTLS step 2..."); gnutls_transport_set_push_function(ssl_data_loc->session, (gnutls_push_func) & internal_ssl_write); debug_info("GnuTLS step 3..."); gnutls_transport_set_pull_function(ssl_data_loc->session, (gnutls_pull_func) & internal_ssl_read); debug_info("GnuTLS step 4 -- now handshaking..."); if (errno) { debug_info("WARNING: errno says %s before handshake!", strerror(errno)); } return_me = gnutls_handshake(ssl_data_loc->session); debug_info("GnuTLS handshake done..."); if (return_me != GNUTLS_E_SUCCESS) { internal_ssl_cleanup(ssl_data_loc); free(ssl_data_loc); debug_info("GnuTLS reported something wrong."); gnutls_perror(return_me); debug_info("oh.. errno says %s", strerror(errno)); } else { connection->ssl_data = ssl_data_loc; ret = IDEVICE_E_SUCCESS; debug_info("SSL mode enabled"); } #endif return ret; }
BOOL tls_accept(rdpTls* tls, BIO* underlying, rdpSettings* settings) { long options = 0; BIO* bio; RSA* rsa; X509* x509; /** * SSL_OP_NO_SSLv2: * * We only want SSLv3 and TLSv1, so disable SSLv2. * SSLv3 is used by, eg. Microsoft RDC for Mac OS X. */ options |= SSL_OP_NO_SSLv2; /** * SSL_OP_NO_COMPRESSION: * * The Microsoft RDP server does not advertise support * for TLS compression, but alternative servers may support it. * This was observed between early versions of the FreeRDP server * and the FreeRDP client, and caused major performance issues, * which is why we're disabling it. */ #ifdef SSL_OP_NO_COMPRESSION options |= SSL_OP_NO_COMPRESSION; #endif /** * SSL_OP_TLS_BLOCK_PADDING_BUG: * * The Microsoft RDP server does *not* support TLS padding. * It absolutely needs to be disabled otherwise it won't work. */ options |= SSL_OP_TLS_BLOCK_PADDING_BUG; /** * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: * * Just like TLS padding, the Microsoft RDP server does not * support empty fragments. This needs to be disabled. */ options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; if (!tls_prepare(tls, underlying, SSLv23_server_method(), options, FALSE)) return FALSE; if (settings->PrivateKeyFile) { bio = BIO_new_file(settings->PrivateKeyFile, "rb+"); if (!bio) { WLog_ERR(TAG, "BIO_new_file failed for private key %s", settings->PrivateKeyFile); return FALSE; } } else if (settings->PrivateKeyContent) { bio = BIO_new_mem_buf(settings->PrivateKeyContent, strlen(settings->PrivateKeyContent)); if (!bio) { WLog_ERR(TAG, "BIO_new_mem_buf failed for private key"); return FALSE; } } else { WLog_ERR(TAG, "no private key defined"); return FALSE; } rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL); BIO_free(bio); if (!rsa) { WLog_ERR(TAG, "invalid private key"); return FALSE; } if (SSL_use_RSAPrivateKey(tls->ssl, rsa) <= 0) { WLog_ERR(TAG, "SSL_CTX_use_RSAPrivateKey_file failed"); RSA_free(rsa); return FALSE; } if (settings->CertificateFile) { bio = BIO_new_file(settings->CertificateFile, "rb+"); if (!bio) { WLog_ERR(TAG, "BIO_new_file failed for certificate %s", settings->CertificateFile); return FALSE; } } else if (settings->CertificateContent) { bio = BIO_new_mem_buf(settings->CertificateContent, strlen(settings->CertificateContent)); if (!bio) { WLog_ERR(TAG, "BIO_new_mem_buf failed for certificate"); return FALSE; } } else { WLog_ERR(TAG, "no certificate defined"); return FALSE; } x509 = PEM_read_bio_X509(bio, NULL, NULL, 0); BIO_free(bio); if (!x509) { WLog_ERR(TAG, "invalid certificate"); return FALSE; } if (SSL_use_certificate(tls->ssl, x509) <= 0) { WLog_ERR(TAG, "SSL_use_certificate_file failed"); X509_free(x509); return FALSE; } #ifndef OPENSSL_NO_TLSEXT /** * The Microsoft iOS clients eventually send a null or even double null * terminated hostname in the SNI TLS extension! * If the length indicator does not equal the hostname strlen OpenSSL * will abort (see openssl:ssl/t1_lib.c). * Here is a tcpdump segment of Microsoft Remote Desktop Client Version * 8.1.7 running on an iPhone 4 with iOS 7.1.2 showing the transmitted * SNI hostname TLV blob when connection to server "abcd": * 00 name_type 0x00 (host_name) * 00 06 length_in_bytes 0x0006 * 61 62 63 64 00 00 host_name "abcd\0\0" * * Currently the only (runtime) workaround is setting an openssl tls * extension debug callback that sets the SSL context's servername_done * to 1 which effectively disables the parsing of that extension type. */ SSL_set_tlsext_debug_callback(tls->ssl, tls_openssl_tlsext_debug_callback); #endif return tls_do_handshake(tls, FALSE) > 0; }
rdpRsaKey* key_new_from_content(const char* keycontent, const char* keyfile) { BIO* bio = NULL; RSA* rsa = NULL; rdpRsaKey* key = NULL; const BIGNUM* rsa_e = NULL; const BIGNUM* rsa_n = NULL; const BIGNUM* rsa_d = NULL; key = (rdpRsaKey*) calloc(1, sizeof(rdpRsaKey)); if (!key) return NULL; bio = BIO_new_mem_buf((void*)keycontent, strlen(keycontent)); if (!bio) goto out_free; rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL); BIO_free(bio); if (!rsa) { WLog_ERR(TAG, "unable to load RSA key from %s: %s.", keyfile, strerror(errno)); goto out_free; } switch (RSA_check_key(rsa)) { case 0: WLog_ERR(TAG, "invalid RSA key in %s", keyfile); goto out_free_rsa; case 1: /* Valid key. */ break; default: WLog_ERR(TAG, "unexpected error when checking RSA key from %s: %s.", keyfile, strerror(errno)); goto out_free_rsa; } RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); if (BN_num_bytes(rsa_e) > 4) { WLog_ERR(TAG, "RSA public exponent too large in %s", keyfile); goto out_free_rsa; } key->ModulusLength = BN_num_bytes(rsa_n); key->Modulus = (BYTE*) malloc(key->ModulusLength); if (!key->Modulus) goto out_free_rsa; BN_bn2bin(rsa_n, key->Modulus); crypto_reverse(key->Modulus, key->ModulusLength); key->PrivateExponentLength = BN_num_bytes(rsa_d); key->PrivateExponent = (BYTE*) malloc(key->PrivateExponentLength); if (!key->PrivateExponent) goto out_free_modulus; BN_bn2bin(rsa_d, key->PrivateExponent); crypto_reverse(key->PrivateExponent, key->PrivateExponentLength); memset(key->exponent, 0, sizeof(key->exponent)); BN_bn2bin(rsa_e, key->exponent + sizeof(key->exponent) - BN_num_bytes(rsa_e)); crypto_reverse(key->exponent, sizeof(key->exponent)); RSA_free(rsa); return key; out_free_modulus: free(key->Modulus); out_free_rsa: RSA_free(rsa); out_free: free(key); return NULL; }
ssh_key* ssh_key_alloc(char* data, int length, char* passphrase) { ssh_key* key; BIO* key_bio; char* public_key; char* pos; /* Create BIO for reading key from memory */ key_bio = BIO_new_mem_buf(data, length); /* If RSA key, load RSA */ if (length > sizeof(SSH_RSA_KEY_HEADER)-1 && memcmp(SSH_RSA_KEY_HEADER, data, sizeof(SSH_RSA_KEY_HEADER)-1) == 0) { RSA* rsa_key; /* Read key */ rsa_key = PEM_read_bio_RSAPrivateKey(key_bio, NULL, NULL, passphrase); if (rsa_key == NULL) return NULL; /* Allocate key */ key = malloc(sizeof(ssh_key)); key->rsa = rsa_key; /* Set type */ key->type = SSH_KEY_RSA; /* Allocate space for public key */ public_key = malloc(4096); pos = public_key; /* Derive public key */ buffer_write_string(&pos, "ssh-rsa", sizeof("ssh-rsa")-1); buffer_write_bignum(&pos, rsa_key->e); buffer_write_bignum(&pos, rsa_key->n); /* Save public key to structure */ key->public_key = public_key; key->public_key_length = pos - public_key; } /* If DSA key, load DSA */ else if (length > sizeof(SSH_DSA_KEY_HEADER)-1 && memcmp(SSH_DSA_KEY_HEADER, data, sizeof(SSH_DSA_KEY_HEADER)-1) == 0) { DSA* dsa_key; /* Read key */ dsa_key = PEM_read_bio_DSAPrivateKey(key_bio, NULL, NULL, passphrase); if (dsa_key == NULL) return NULL; /* Allocate key */ key = malloc(sizeof(ssh_key)); key->dsa = dsa_key; /* Set type */ key->type = SSH_KEY_DSA; /* Allocate space for public key */ public_key = malloc(4096); pos = public_key; /* Derive public key */ buffer_write_string(&pos, "ssh-dss", sizeof("ssh-dss")-1); buffer_write_bignum(&pos, dsa_key->p); buffer_write_bignum(&pos, dsa_key->q); buffer_write_bignum(&pos, dsa_key->g); buffer_write_bignum(&pos, dsa_key->pub_key); /* Save public key to structure */ key->public_key = public_key; key->public_key_length = pos - public_key; } /* Otherwise, unsupported type */ else { BIO_free(key_bio); return NULL; } /* Copy private key to structure */ key->private_key_length = length; key->private_key = malloc(length); memcpy(key->private_key, data, length); BIO_free(key_bio); return key; }
static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm) { X509 *cert = NULL; BIO *bio = NULL; BIO *kbio = NULL; RSA *rsa = NULL; int ret; const char *mypem = /* www.cacert.org */ "-----BEGIN CERTIFICATE-----\n"\ "MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290\n"\ "IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB\n"\ "IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA\n"\ "Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO\n"\ "BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi\n"\ "MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ\n"\ "ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC\n"\ "CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ\n"\ "8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6\n"\ "zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y\n"\ "fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7\n"\ "w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc\n"\ "G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k\n"\ "epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q\n"\ "laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ\n"\ "QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU\n"\ "fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826\n"\ "YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w\n"\ "ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY\n"\ "gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe\n"\ "MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0\n"\ "IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy\n"\ "dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw\n"\ "czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0\n"\ "dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl\n"\ "aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC\n"\ "AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg\n"\ "b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB\n"\ "ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc\n"\ "nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg\n"\ "18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c\n"\ "gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl\n"\ "Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY\n"\ "sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T\n"\ "SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF\n"\ "CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum\n"\ "GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk\n"\ "zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW\n"\ "omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD\n"\ "-----END CERTIFICATE-----\n"; /*replace the XXX with the actual RSA key*/ const char *mykey = "-----BEGIN RSA PRIVATE KEY-----\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "-----END RSA PRIVATE KEY-----\n"; (void)curl; /* avoid warnings */ (void)parm; /* avoid warnings */ /* get a BIO */ bio = BIO_new_mem_buf((char *)mypem, -1); if(bio == NULL) { printf("BIO_new_mem_buf failed\n"); } /* use it to read the PEM formatted certificate from memory into an X509 * structure that SSL can use */ cert = PEM_read_bio_X509(bio, NULL, 0, NULL); if(cert == NULL) { printf("PEM_read_bio_X509 failed...\n"); } /*tell SSL to use the X509 certificate*/ ret = SSL_CTX_use_certificate((SSL_CTX*)sslctx, cert); if(ret != 1) { printf("Use certificate failed\n"); } /*create a bio for the RSA key*/ kbio = BIO_new_mem_buf((char *)mykey, -1); if(kbio == NULL) { printf("BIO_new_mem_buf failed\n"); } /*read the key bio into an RSA object*/ rsa = PEM_read_bio_RSAPrivateKey(kbio, NULL, 0, NULL); if(rsa == NULL) { printf("Failed to create key bio\n"); } /*tell SSL to use the RSA key from memory*/ ret = SSL_CTX_use_RSAPrivateKey((SSL_CTX*)sslctx, rsa); if(ret != 1) { printf("Use Key failed\n"); } /* free resources that have been allocated by openssl functions */ if(bio) BIO_free(bio); if(kbio) BIO_free(kbio); if(rsa) RSA_free(rsa); if(cert) X509_free(cert); /* all set to go */ return CURLE_OK; }
uint32_t AMAuthInstallCryptoRegisterKeysFromPEMBuffer(CFDictionaryRef dict, CFStringRef key, CFTypeRef value, void* context) { LODWORD(r14) = LODWORD(rcx); r12 = rdx; rbx = rsi; r13 = rdi; uint32_t result = AMAuthInstallCryptoGetKeyIdType(key); if ((result & 0x8) == 0x0) { // loc_428fc; if ((result & 0x4) == 0x0) { // loc_4291d; CFStringRef pub_key_name = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@.public"), key); LODWORD(r15) = 0x2; if (!pub_key_name) { // loc_42cf2; LODWORD(r13) = 0x0; LODWORD(rbx) = 0x0; var_24 = 0x0; LODWORD(r14) = 0x0; LODWORD(r12) = 0x0; // loc_42c0d; // goto exit } // loc_4295c; CFStringRef private_key_name = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@.private"), key); if (!private_key_name) { // loc_42d0d; LODWORD(r13) = 0x0; var_24 = 0x0; // loc_42bc9: LODWORD(r14) = 0x0; LODWORD(r12) = 0x0; rbx = var_40; // loc_42c0d; // goto exit } // loc_4298e; LOBYTE(r15) = 0x1; var_16 = 0x1; } else { // loc_42900; var_40 = CFRetain(rbx); LOBYTE(r15) = 0x0; var_16 = 0x1; LODWORD(rax) = 0x0; // loc_42998; } } else { // loc_428da; rax = CFRetain(rbx); LOBYTE(r15) = 0x1; var_16 = 0x0; var_40 = 0x0; } // loc_42998; var_8 = r13; var_24 = rax; rbx = BIO_new_mem_buf(r12, LODWORD(r14)); if (rbx == 0x0) { // loc_42be7; var_32 = 0x0; LODWORD(r13) = 0x0; LODWORD(r14) = 0x0; // loc_42bf8: LODWORD(r12) = 0x0; // loc_42c00: rbx = var_40; LODWORD(r15) = 0x2; // loc_42c0d; // goto exit } // loc_429bd; rdi = rbx; if (LOBYTE(r15) != 0x0) { rax = PEM_read_bio_RSAPrivateKey(rdi, 0x0, 0x0, 0x0); } else { rax = PEM_read_bio_RSA_PUBKEY(rdi, 0x0, 0x0, 0x0); } r13 = rax; var_32 = rbx; if (r13 == 0x0) { // loc_42b77; rax = ERR_get_error(); rbx = &var_64; ERR_error_string(rax, rbx); if (LOBYTE(r15) != 0x0) { } _AMAuthInstallLog(0x3, "AMAuthInstallCryptoRegisterKeysFromPEMBuffer", "PEM_read_bio_RSA%sKey() failed: %s"); LODWORD(r15) = 0x6; LODWORD(r13) = 0x0; // loc_42bc9; LODWORD(r14) = 0x0; LODWORD(r12) = 0x0; rbx = var_40; // loc_42c0d; // goto exit } else { // loc_429ea; LODWORD(r14) = 0x0; uint32_t private_key_length = i2d_RSAPrivateKey(r13, NULL); CFDataRef private_key = CFDataCreateMutable(kCFAllocatorDefault, private_key_length); if (private_key) { // loc_42a2c; CFDataSetLength(private_key, private_key_length); UInt8 *data_ptr = CFDataGetMutableBytePtr(private_key); i2d_RSAPrivateKey(r13, data_ptr); CFDictionarySetValue(*(r15 + 0x140), private_key_name, private_key); // loc_42a6b; } if (LOBYTE(r15) == 0x0 || private_key) { // loc_42a6b; if (var_16 == 0x0) { // loc_42bd8; LODWORD(r12) = 0x0; LODWORD(r15) = 0x0; rbx = var_40; // loc_42c0d; // goto exit } else { // loc_42a78; uint32_t pub_key_length = i2d_RSAPublicKey(r13, NULL); CFDataRef pub_key = CFDataCreateMutable(kCFAllocatorDefault, pub_key_length); if (pub_key == 0x0) { // loc_42bf8; LODWORD(r12) = 0x0; // loc_42c00: rbx = var_40; LODWORD(r15) = 0x2; // loc_42c0d; // goto exit } var_0 = r14; CFDataSetLength(pub_key, pub_key_length); UInt8 *pub_key_ptr = CFDataGetMutableBytePtr(pub_key); i2d_RSAPublicKey(r13, pub_key_ptr); CFDictionarySetValue(dict, pub_key_name, pub_key); Pointer digest = NULL; LODWORD(r15) = AMAuthInstallCryptoCreateDigestForKey(dict, pub_key_name, &digest)); if (LODWORD(r15) == 0x0) { var_16 = r13; if (var_64 != 0x0) { CFDictionarySetValue(install->ivars.digests, var_64, rbx); LODWORD(r13) = 0x0; } else { _AMAuthInstallLog(0x3, "_AMAuthInstallCryptoRegisterKeyHash", "keyHashData is NULL"); LODWORD(r13) = 0x0; LODWORD(r15) = 0x0; } } else { var_16 = r13; AMAuthInstallLog(0x3, "_AMAuthInstallCryptoRegisterKeyHash", "AMAuthInstallCryptoCreateDigestForKey(%@) failed", rbx); LODWORD(r13) = LODWORD(r15); r15 = var_64; } _SafeRelease(r15); LODWORD(r15) = LODWORD(r13); r14 = var_0; if (LODWORD(r13) == 0x0) { LODWORD(r15) = 0x0; } else { AMAuthInstallLog(0x3, "AMAuthInstallCryptoRegisterKeysFromPEMBuffer", "AMAuthInstallCryptoRegisterKeyHash(%@) failed", rbx); } r13 = var_16; // loc_42c0d; // goto exit } } } // loc_42c0d: _SafeRelease(rbx); _SafeRelease(var_24); _SafeRelease(r14); _SafeRelease(r12); if (r13 != 0x0) { RSA_free(r13); } rdi = var_32; if (rdi != 0x0) { BIO_free(rdi); } return result; }
BOOL tls_accept(rdpTls* tls, BIO* underlying, rdpSettings* settings) { long options = 0; BIO* bio; RSA* rsa; X509* x509; /** * SSL_OP_NO_SSLv2: * * We only want SSLv3 and TLSv1, so disable SSLv2. * SSLv3 is used by, eg. Microsoft RDC for Mac OS X. */ options |= SSL_OP_NO_SSLv2; /** * SSL_OP_NO_COMPRESSION: * * The Microsoft RDP server does not advertise support * for TLS compression, but alternative servers may support it. * This was observed between early versions of the FreeRDP server * and the FreeRDP client, and caused major performance issues, * which is why we're disabling it. */ #ifdef SSL_OP_NO_COMPRESSION options |= SSL_OP_NO_COMPRESSION; #endif /** * SSL_OP_TLS_BLOCK_PADDING_BUG: * * The Microsoft RDP server does *not* support TLS padding. * It absolutely needs to be disabled otherwise it won't work. */ options |= SSL_OP_TLS_BLOCK_PADDING_BUG; /** * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: * * Just like TLS padding, the Microsoft RDP server does not * support empty fragments. This needs to be disabled. */ options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; if (!tls_prepare(tls, underlying, SSLv23_server_method(), options, FALSE)) return FALSE; if (settings->PrivateKeyFile) { bio = BIO_new_file(settings->PrivateKeyFile, "rb"); if (!bio) { WLog_ERR(TAG, "BIO_new_file failed for private key %s", settings->PrivateKeyFile); return FALSE; } } else if (settings->PrivateKeyContent) { bio = BIO_new_mem_buf(settings->PrivateKeyContent, strlen(settings->PrivateKeyContent)); if (!bio) { WLog_ERR(TAG, "BIO_new_mem_buf failed for private key"); return FALSE; } } else { WLog_ERR(TAG, "no private key defined"); return FALSE; } rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL); BIO_free(bio); if (!rsa) { WLog_ERR(TAG, "invalid private key"); return FALSE; } if (SSL_use_RSAPrivateKey(tls->ssl, rsa) <= 0) { WLog_ERR(TAG, "SSL_CTX_use_RSAPrivateKey_file failed"); RSA_free(rsa); return FALSE; } if (settings->CertificateFile) { bio = BIO_new_file(settings->CertificateFile, "rb"); if (!bio) { WLog_ERR(TAG, "BIO_new_file failed for certificate %s", settings->CertificateFile); return FALSE; } } else if (settings->CertificateContent) { bio = BIO_new_mem_buf(settings->CertificateContent, strlen(settings->CertificateContent)); if (!bio) { WLog_ERR(TAG, "BIO_new_mem_buf failed for certificate"); return FALSE; } } else { WLog_ERR(TAG, "no certificate defined"); return FALSE; } x509 = PEM_read_bio_X509(bio, NULL, NULL, 0); BIO_free(bio); if (!x509) { WLog_ERR(TAG, "invalid certificate"); return FALSE; } if (SSL_use_certificate(tls->ssl, x509) <= 0) { WLog_ERR(TAG, "SSL_use_certificate_file failed"); X509_free(x509); return FALSE; } #if defined(MICROSOFT_IOS_SNI_BUG) && !defined(OPENSSL_NO_TLSEXT) SSL_set_tlsext_debug_callback(tls->ssl, tls_openssl_tlsext_debug_callback); #endif return tls_do_handshake(tls, FALSE) > 0; }
ssh_key pki_private_key_from_base64(ssh_session session, const char *b64_key, const char *passphrase) { BIO *mem = NULL; DSA *dsa = NULL; RSA *rsa = NULL; ssh_key key; enum ssh_keytypes_e type; /* needed for openssl initialization */ if (ssh_init() < 0) { return NULL; } type = pki_privatekey_type_from_string(b64_key); if (type == SSH_KEYTYPE_UNKNOWN) { ssh_set_error(session, SSH_FATAL, "Unknown or invalid private key."); return NULL; } mem = BIO_new_mem_buf((void*)b64_key, -1); switch (type) { case SSH_KEYTYPE_DSS: if (passphrase == NULL) { if (session->common.callbacks && session->common.callbacks->auth_function) { dsa = PEM_read_bio_DSAPrivateKey(mem, NULL, pem_get_password, session); } else { /* openssl uses its own callback to get the passphrase here */ dsa = PEM_read_bio_DSAPrivateKey(mem, NULL, NULL, NULL); } } else { dsa = PEM_read_bio_DSAPrivateKey(mem, NULL, NULL, (void *) passphrase); } BIO_free(mem); if (dsa == NULL) { ssh_set_error(session, SSH_FATAL, "Parsing private key: %s", ERR_error_string(ERR_get_error(), NULL)); return NULL; } break; case SSH_KEYTYPE_RSA: case SSH_KEYTYPE_RSA1: if (passphrase == NULL) { if (session->common.callbacks && session->common.callbacks->auth_function) { rsa = PEM_read_bio_RSAPrivateKey(mem, NULL, pem_get_password, session); } else { /* openssl uses its own callback to get the passphrase here */ rsa = PEM_read_bio_RSAPrivateKey(mem, NULL, NULL, NULL); } } else { rsa = PEM_read_bio_RSAPrivateKey(mem, NULL, NULL, (void *) passphrase); } BIO_free(mem); if (rsa == NULL) { ssh_set_error(session, SSH_FATAL, "Parsing private key: %s", ERR_error_string(ERR_get_error(),NULL)); return NULL; } break; case SSH_KEYTYPE_ECDSA: case SSH_KEYTYPE_UNKNOWN: BIO_free(mem); ssh_set_error(session, SSH_FATAL, "Unkown or invalid private key type %d", type); return NULL; } key = ssh_key_new(); if (key == NULL) { goto fail; } key->type = type; key->type_c = ssh_key_type_to_char(type); key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC; key->dsa = dsa; key->rsa = rsa; return key; fail: ssh_key_free(key); DSA_free(dsa); RSA_free(rsa); return NULL; }