diff --git a/libgamestream/client.c b/libgamestream/client.c index 121f3ae..4d55e39 100644 --- a/libgamestream/client.c +++ b/libgamestream/client.c @@ -350,6 +350,30 @@ static bool verifySignature(const char *data, int dataLength, char *signature, i return result > 0; } +static void encrypt(const unsigned char *plaintext, int plaintextLen, const unsigned char *key, unsigned char *ciphertext) { + EVP_CIPHER_CTX* cipher = EVP_CIPHER_CTX_new(); + + EVP_EncryptInit(cipher, EVP_aes_128_ecb(), key, NULL); + EVP_CIPHER_CTX_set_padding(cipher, 0); + + int ciphertextLen = 0; + EVP_EncryptUpdate(cipher, ciphertext, &ciphertextLen, plaintext, plaintextLen); + + EVP_CIPHER_CTX_free(cipher); +} + +static void decrypt(const unsigned char *ciphertext, int ciphertextLen, const unsigned char *key, unsigned char *plaintext) { + EVP_CIPHER_CTX* cipher = EVP_CIPHER_CTX_new(); + + EVP_DecryptInit(cipher, EVP_aes_128_ecb(), key, NULL); + EVP_CIPHER_CTX_set_padding(cipher, 0); + + int plaintextLen = 0; + EVP_DecryptUpdate(cipher, plaintext, &plaintextLen, ciphertext, ciphertextLen); + + EVP_CIPHER_CTX_free(cipher); +} + int gs_unpair(PSERVER_DATA server) { int ret = GS_OK; char url[4096]; @@ -428,25 +452,21 @@ int gs_pair(PSERVER_DATA server, char* pin) { plaincert[strlen(result)/2] = '\0'; unsigned char salt_pin[20]; - unsigned char aes_key_hash[32]; - AES_KEY enc_key, dec_key; + unsigned char aes_key[32]; memcpy(salt_pin, salt_data, 16); memcpy(salt_pin+16, pin, 4); int hash_length = server->serverMajorVersion >= 7 ? 32 : 20; if (server->serverMajorVersion >= 7) - SHA256(salt_pin, 20, aes_key_hash); + SHA256(salt_pin, 20, aes_key); else - SHA1(salt_pin, 20, aes_key_hash); - - AES_set_encrypt_key((unsigned char *)aes_key_hash, 128, &enc_key); - AES_set_decrypt_key((unsigned char *)aes_key_hash, 128, &dec_key); + SHA1(salt_pin, 20, aes_key); unsigned char challenge_data[16]; unsigned char challenge_enc[16]; char challenge_hex[33]; RAND_bytes(challenge_data, 16); - AES_encrypt(challenge_data, challenge_enc, &enc_key); + encrypt(challenge_data, 16, aes_key, challenge_enc); bytes_to_hex(challenge_enc, challenge_hex, 16); uuid_generate_random(uuid); @@ -481,9 +501,7 @@ int gs_pair(PSERVER_DATA server, char* pin) { sscanf(&result[count], "%2hhx", &challenge_response_data_enc[count / 2]); } - for (int i = 0; i < 48; i += 16) { - AES_decrypt(&challenge_response_data_enc[i], &challenge_response_data[i], &dec_key); - } + decrypt(challenge_response_data_enc, 48, aes_key, challenge_response_data); char client_secret_data[16]; RAND_bytes(client_secret_data, 16); @@ -503,9 +521,7 @@ int gs_pair(PSERVER_DATA server, char* pin) { else SHA1(challenge_response, 16 + 256 + 16, challenge_response_hash); - for (int i = 0; i < 32; i += 16) { - AES_encrypt(&challenge_response_hash[i], &challenge_response_hash_enc[i], &enc_key); - } + encrypt(challenge_response_hash, 32, aes_key, challenge_response_hash_enc); bytes_to_hex(challenge_response_hash_enc, challenge_response_hex, 32); uuid_generate_random(uuid); diff --git a/libgamestream/mkcert.c b/libgamestream/mkcert.c index 2f8007d..64fede0 100644 --- a/libgamestream/mkcert.c +++ b/libgamestream/mkcert.c @@ -39,7 +39,6 @@ CERT_KEY_PAIR mkcert_generate() { EVP_PKEY *pkey = NULL; PKCS12 *p12 = NULL; - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); OpenSSL_add_all_algorithms(); @@ -81,71 +80,47 @@ void mkcert_save(const char* certFile, const char* p12File, const char* keyPairF } int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int years) { - X509 *x; - EVP_PKEY *pk; - RSA *rsa; - X509_NAME *name = NULL; + EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); + EVP_PKEY_keygen_init(ctx); + EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits); - if (*pkeyp == NULL) { - if ((pk=EVP_PKEY_new()) == NULL) { - abort(); - return(0); - } - } else { - pk = *pkeyp; - } + // pk must be initialized on input + EVP_PKEY *pk = NULL;; + EVP_PKEY_keygen(ctx, &pk); - if (*x509p == NULL) { - if ((x = X509_new()) == NULL) { - goto err; - } - } else { - x = *x509p; - } + EVP_PKEY_CTX_free(ctx); - if ((rsa = RSA_new()) == NULL) - goto err; + X509* cert = X509_new(); + X509_set_version(cert, 2); + ASN1_INTEGER_set(X509_get_serialNumber(cert), serial); +#if OPENSSL_VERSION_NUMBER < 0x10100000L + X509_gmtime_adj(X509_get_notBefore(cert), 0); + X509_gmtime_adj(X509_get_notAfter(cert), 60 * 60 * 24 * 365 * years); +#else + ASN1_TIME* before = ASN1_STRING_dup(X509_get0_notBefore(cert)); + ASN1_TIME* after = ASN1_STRING_dup(X509_get0_notAfter(cert)); - BIGNUM* bne = BN_new(); - if (bne == NULL) { - abort(); - goto err; - } + X509_gmtime_adj(before, 0); + X509_gmtime_adj(after, 60 * 60 * 24 * 365 * years); - BN_set_word(bne, RSA_F4); - if (RSA_generate_key_ex(rsa, bits, bne, NULL) == 0) { - abort(); - goto err; - } + X509_set1_notBefore(cert, before); + X509_set1_notAfter(cert, after); - if (!EVP_PKEY_assign_RSA(pk, rsa)) { - abort(); - goto err; - } + ASN1_STRING_free(before); + ASN1_STRING_free(after); +#endif - X509_set_version(x, 2); - ASN1_INTEGER_set(X509_get_serialNumber(x), serial); - X509_gmtime_adj(X509_get_notBefore(x), 0); - X509_gmtime_adj(X509_get_notAfter(x), (long)60*60*24*365*years); - X509_set_pubkey(x, pk); + X509_set_pubkey(cert, pk); - name = X509_get_subject_name(x); - - /* This function creates and adds the entry, working out the - * correct string type and performing checks on its length. - */ + X509_NAME* name = X509_get_subject_name(cert); X509_NAME_add_entry_by_txt(name,"CN", MBSTRING_ASC, (unsigned char*)"NVIDIA GameStream Client", -1, -1, 0); + X509_set_issuer_name(cert, name); - /* Its self signed so set the issuer name to be the same as the - * subject. - */ - X509_set_issuer_name(x, name); - - if (!X509_sign(x, pk, EVP_sha256())) { + if (!X509_sign(cert, pk, EVP_sha256())) { goto err; } - *x509p = x; + *x509p = cert; *pkeyp = pk; return(1);