static BOOL certificate_process_server_public_signature(rdpCertificate* certificate, const BYTE* sigdata, int sigdatalen, wStream* s, UINT32 siglen) { int i, sum; CryptoMd5 md5ctx; BYTE sig[TSSK_KEY_LENGTH]; BYTE encsig[TSSK_KEY_LENGTH + 8]; BYTE md5hash[CRYPTO_MD5_DIGEST_LENGTH]; md5ctx = crypto_md5_init(); if (!md5ctx) return FALSE; crypto_md5_update(md5ctx, sigdata, sigdatalen); crypto_md5_final(md5ctx, md5hash); Stream_Read(s, encsig, siglen); /* Last 8 bytes shall be all zero. */ for (sum = 0, i = sizeof(encsig) - 8; i < sizeof(encsig); i++) sum += encsig[i]; if (sum != 0) { WLog_ERR(TAG, "invalid signature"); //return FALSE; } siglen -= 8; // TODO: check the result of decrypt crypto_rsa_public_decrypt(encsig, siglen, TSSK_KEY_LENGTH, tssk_modulus, tssk_exponent, sig); /* Verify signature. */ if (memcmp(md5hash, sig, sizeof(md5hash)) != 0) { WLog_ERR(TAG, "invalid signature"); //return FALSE; } /* * Verify rest of decrypted data: * The 17th byte is 0x00. * The 18th through 62nd bytes are each 0xFF. * The 63rd byte is 0x01. */ for (sum = 0, i = 17; i < 62; i++) sum += sig[i]; if (sig[16] != 0x00 || sum != 0xFF * (62 - 17) || sig[62] != 0x01) { WLog_ERR(TAG, "invalid signature"); //return FALSE; } return TRUE; }
static boolean certificate_process_server_public_signature(rdpCertificate* certificate, uint8* sigdata, int sigdatalen, STREAM* s, uint32 siglen) { uint8 md5hash[CRYPTO_MD5_DIGEST_LENGTH]; uint8 encsig[TSSK_KEY_LENGTH + 8]; uint8 sig[TSSK_KEY_LENGTH]; CryptoMd5 md5ctx; int i, sum; md5ctx = crypto_md5_init(); crypto_md5_update(md5ctx, sigdata, sigdatalen); crypto_md5_final(md5ctx, md5hash); stream_read(s, encsig, siglen); /* Last 8 bytes shall be all zero. */ for (sum = 0, i = sizeof(encsig) - 8; i < sizeof(encsig); i++) sum += encsig[i]; if (sum != 0) { printf("certificate_process_server_public_signature: invalid signature\n"); //return false; } siglen -= 8; crypto_rsa_public_decrypt(encsig, siglen, TSSK_KEY_LENGTH, tssk_modulus, tssk_exponent, sig); /* Verify signature. */ if (memcmp(md5hash, sig, sizeof(md5hash)) != 0) { printf("certificate_process_server_public_signature: invalid signature\n"); //return false; } /* * Verify rest of decrypted data: * The 17th byte is 0x00. * The 18th through 62nd bytes are each 0xFF. * The 63rd byte is 0x01. */ for (sum = 0, i = 17; i < 62; i++) sum += sig[i]; if (sig[16] != 0x00 || sum != 0xFF * (62 - 17) || sig[62] != 0x01) { printf("certificate_process_server_public_signature: invalid signature\n"); //return false; } return true; }
static BOOL certificate_process_server_public_signature(rdpCertificate* certificate, const BYTE* sigdata, size_t sigdatalen, wStream* s, UINT32 siglen) { #if defined(CERT_VALIDATE_PADDING) || defined(CERT_VALIDATE_RSA) size_t i, sum; #endif #if defined(CERT_VALIDATE_RSA) BYTE sig[TSSK_KEY_LENGTH]; #endif BYTE encsig[TSSK_KEY_LENGTH + 8]; #if defined(CERT_VALIDATE_MD5) && defined(CERT_VALIDATE_RSA) BYTE md5hash[WINPR_MD5_DIGEST_LENGTH]; #endif #if !defined(CERT_VALIDATE_MD5) || !defined(CERT_VALIDATE_RSA) (void)sigdata; (void)sigdatalen; #endif (void)certificate; /* Do not bother with validation of server proprietary certificate. The use of MD5 here is not allowed under FIPS. * Since the validation is not protecting against anything since the private/public keys are well known and documented in * MS-RDPBCGR section 5.3.3.1, we are not gaining any security by using MD5 for signature comparison. Rather then use MD5 * here we just dont do the validation to avoid its use. Historically, freerdp has been ignoring a failed validation anyways. */ #if defined(CERT_VALIDATE_MD5) if (!winpr_Digest(WINPR_MD_MD5, sigdata, sigdatalen, md5hash, sizeof(md5hash))) return FALSE; #endif Stream_Read(s, encsig, siglen); /* Last 8 bytes shall be all zero. */ #if defined(CERT_VALIDATE_PADDING) for (sum = 0, i = sizeof(encsig) - 8; i < sizeof(encsig); i++) sum += encsig[i]; if (sum != 0) { WLog_ERR(TAG, "invalid signature"); return FALSE; } #endif siglen -= 8; #if defined(CERT_VALIDATE_RSA) if (crypto_rsa_public_decrypt(encsig, siglen, TSSK_KEY_LENGTH, tssk_modulus, tssk_exponent, sig) <= 0) { WLog_ERR(TAG, "invalid RSA decrypt"); return FALSE; } /* Verify signature. */ /* Do not bother with validation of server proprietary certificate as described above. */ #if defined(CERT_VALIDATE_MD5) if (memcmp(md5hash, sig, sizeof(md5hash)) != 0) { WLog_ERR(TAG, "invalid signature"); return FALSE; } #endif /* * Verify rest of decrypted data: * The 17th byte is 0x00. * The 18th through 62nd bytes are each 0xFF. * The 63rd byte is 0x01. */ for (sum = 0, i = 17; i < 62; i++) sum += sig[i]; if (sig[16] != 0x00 || sum != 0xFF * (62 - 17) || sig[62] != 0x01) { WLog_ERR(TAG, "invalid signature"); return FALSE; } #endif return TRUE; }