bool CryptManager::Sign( RString sPath, RString &sSignatureOut, RString sPrivKey ) { if( !IsAFile(sPath) ) { LOG->Trace( "SignFileToFile: \"%s\" doesn't exist", sPath.c_str() ); return false; } RageFile file; if( !file.Open(sPath) ) { LOG->Warn( "SignFileToFile: open(%s) failed: %s", sPath.c_str(), file.GetError().c_str() ); return false; } RSAKeyWrapper key; RString sError; if( !key.Load(sPrivKey, sError) ) { LOG->Warn( "Error loading RSA key: %s", sError.c_str() ); return false; } int iHash = register_hash( &sha1_desc ); ASSERT( iHash >= 0 ); unsigned char buf_hash[20]; if( !HashFile(file, buf_hash, iHash) ) return false; unsigned char signature[256]; unsigned long signature_len = sizeof(signature); int iRet = rsa_sign_hash_ex( buf_hash, sizeof(buf_hash), signature, &signature_len, LTC_PKCS_1_V1_5, &g_pPRNG->m_PRNG, g_pPRNG->m_iPRNG, iHash, 0, &key.m_Key); if( iRet != CRYPT_OK ) { LOG->Warn( "SignFileToFile error: %s", error_to_string(iRet) ); return false; } sSignatureOut.assign( (const char *) signature, signature_len ); return true; }
int SSignFileFinish(TMPQArchive * ha) { MPQ_SIGNATURE_INFO si; unsigned long signature_len = MPQ_WEAK_SIGNATURE_SIZE; BYTE WeakSignature[MPQ_SIGNATURE_FILE_SIZE]; BYTE Md5Digest[MD5_DIGEST_SIZE]; rsa_key key; int hash_idx = find_hash("md5"); // Sanity checks assert((ha->dwFlags & MPQ_FLAG_CHANGED) == 0); assert(ha->dwFileFlags3 == MPQ_FILE_EXISTS); // Query the weak signature info memset(&si, 0, sizeof(MPQ_SIGNATURE_INFO)); if(!QueryMpqSignatureInfo(ha, &si)) return ERROR_FILE_CORRUPT; // There must be exactly one signature if(si.SignatureTypes != SIGNATURE_TYPE_WEAK) return ERROR_FILE_CORRUPT; // Calculate MD5 of the entire archive if(!CalculateMpqHashMd5(ha, &si, Md5Digest)) return ERROR_VERIFY_FAILED; // Decode the private key if(!decode_base64_key(szBlizzardWeakPrivateKey, &key)) return ERROR_VERIFY_FAILED; // Sign the hash memset(WeakSignature, 0, sizeof(WeakSignature)); rsa_sign_hash_ex(Md5Digest, sizeof(Md5Digest), WeakSignature + 8, &signature_len, LTC_LTC_PKCS_1_V1_5, 0, 0, hash_idx, 0, &key); memrev(WeakSignature + 8, MPQ_WEAK_SIGNATURE_SIZE); rsa_free(&key); // Write the signature to the MPQ. Don't use SFile* functions, but write the hash directly if(!FileStream_Write(ha->pStream, &si.BeginExclude, WeakSignature, MPQ_SIGNATURE_FILE_SIZE)) return GetLastError(); return ERROR_SUCCESS; }
static int rpmltcSignRSA(pgpDig dig) /*@*/ { rpmltc ltc = dig->impl; int rc = 0; /* assume failure. */ int _padding = LTC_LTC_PKCS_1_V1_5; int hash_idx = find_hash("sha1"); unsigned long saltlen = 0; unsigned char sig[2048]; unsigned long siglen = sizeof(sig); if (ltc->digest == NULL || ltc->digestlen == 0) goto exit; #ifdef NOTYET rc = rpmltcErr(ltc, "rsa_sign_hash_ex", rsa_sign_hash_ex(ltc->digest, ltc->digestlen, sig, &siglen, _padding, &yarrow_prng, find_prng("yarrow"), hash_idx, saltlen, <c->rsa)); #else rc = rpmltcErr(ltc, "rsa_encrypt_key_ex", rsa_encrypt_key_ex(ltc->digest, ltc->digestlen, sig, &siglen, NULL, 0, &yarrow_prng, find_prng("yarrow"), hash_idx, _padding, <c->rsa)); #endif if (rc == CRYPT_OK) { int xx; _initBN(ltc->c); xx = mp_read_unsigned_bin(ltc->c, sig, siglen); } #ifdef DYING rpmltcDumpRSA(__FUNCTION__, ltc); #endif rc = (rc == CRYPT_OK); exit: SPEW(!rc, rc, dig); return rc; }
int pkcs_1_emsa_test(void) { int hash_idx = find_hash("sha1"); unsigned int i; unsigned int j; DO(hash_is_valid(hash_idx)); for (i = 0; i < sizeof(testcases_emsa)/sizeof(testcases_emsa[0]); ++i) { testcase_t* t = &testcases_emsa[i]; rsa_key k, *key = &k; DOX(mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL), t->name); DOX(mp_read_unsigned_bin(key->e, t->rsa.e, t->rsa.e_l), t->name); DOX(mp_read_unsigned_bin(key->d, t->rsa.d, t->rsa.d_l), t->name); DOX(mp_read_unsigned_bin(key->N, t->rsa.n, t->rsa.n_l), t->name); DOX(mp_read_unsigned_bin(key->dQ, t->rsa.dQ, t->rsa.dQ_l), t->name); DOX(mp_read_unsigned_bin(key->dP, t->rsa.dP, t->rsa.dP_l), t->name); DOX(mp_read_unsigned_bin(key->qP, t->rsa.qInv, t->rsa.qInv_l), t->name); DOX(mp_read_unsigned_bin(key->q, t->rsa.q, t->rsa.q_l), t->name); DOX(mp_read_unsigned_bin(key->p, t->rsa.p, t->rsa.p_l), t->name); key->type = PK_PRIVATE; for (j = 0; j < sizeof(t->data)/sizeof(t->data[0]); ++j) { rsaData_t* s = &t->data[j]; unsigned char buf[20], obuf[256]; unsigned long buflen = sizeof(buf), obuflen = sizeof(obuf); int stat; DOX(hash_memory(hash_idx, s->o1, s->o1_l, buf, &buflen), s->name); DOX(rsa_sign_hash_ex(buf, buflen, obuf, &obuflen, LTC_PKCS_1_V1_5, NULL, -1, hash_idx, 0, key), s->name); DOX(obuflen == (unsigned long)s->o2_l?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name); DOX(memcmp(s->o2, obuf, s->o2_l)==0?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name); DOX(rsa_verify_hash_ex(obuf, obuflen, buf, buflen, LTC_PKCS_1_V1_5, hash_idx, 0, &stat, key), s->name); DOX(stat == 1?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name); } /* for */ mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL); } /* for */ return 0; }
bool CryptHelpers::SignFile( RageFileBasic &file, CString sPrivKey, CString &sSignatureOut, CString &sError ) { #ifdef _XBOX return false; #else unsigned char embedded_key[4096], filehash[20], sig[128]; unsigned long keysize = 4096, sigsize = 128; int ret; rsa_key key; bool bDecoded = PKCS8DecodePrivateKey((const unsigned char *)sPrivKey.data(), sPrivKey.size(), embedded_key, keysize); if ( bDecoded ) sPrivKey.assign((const char*)embedded_key, keysize); ret = rsa_import((const unsigned char*)sPrivKey.data(), sPrivKey.size(), &key); if ( ret != CRYPT_OK ) { LOG->Warn("Could not import private key: %s", error_to_string(ret)); return false; } bool bShaRet = GetSha1ForFile(file, filehash); if ( !bShaRet ) { LOG->Warn("Could not get SHA1 for file"); return false; } ret = rsa_sign_hash_ex( filehash, 20, sig, &sigsize, LTC_LTC_PKCS_1_V1_5, &g_PRNGState, g_PRNGDescId, g_SHA1DescId, 0, &key ); if ( ret != CRYPT_OK ) { LOG->Warn("Could not sign hash file: %s", error_to_string(ret)); return false; } ASSERT( sigsize == 128 ); sSignatureOut.assign( (const char *)sig, sigsize ); return true; #endif }
int rsa_test(void) { unsigned char in[1024], out[1024], tmp[1024]; rsa_key key, privKey, pubKey; int hash_idx, prng_idx, stat, stat2; unsigned long rsa_msgsize, len, len2, cnt; static unsigned char lparam[] = { 0x01, 0x02, 0x03, 0x04 }; if (rsa_compat_test() != 0) { return 1; } hash_idx = find_hash("sha1"); prng_idx = find_prng("yarrow"); if (hash_idx == -1 || prng_idx == -1) { fprintf(stderr, "rsa_test requires LTC_SHA1 and yarrow"); return 1; } /* make 10 random key */ for (cnt = 0; cnt < 10; cnt++) { DO(rsa_make_key(&yarrow_prng, prng_idx, 1024/8, 65537, &key)); if (mp_count_bits(key.N) != 1024) { fprintf(stderr, "rsa_1024 key modulus has %d bits\n", mp_count_bits(key.N)); len = mp_unsigned_bin_size(key.N); mp_to_unsigned_bin(key.N, tmp); fprintf(stderr, "N == \n"); for (cnt = 0; cnt < len; ) { fprintf(stderr, "%02x ", tmp[cnt]); if (!(++cnt & 15)) fprintf(stderr, "\n"); } len = mp_unsigned_bin_size(key.p); mp_to_unsigned_bin(key.p, tmp); fprintf(stderr, "p == \n"); for (cnt = 0; cnt < len; ) { fprintf(stderr, "%02x ", tmp[cnt]); if (!(++cnt & 15)) fprintf(stderr, "\n"); } len = mp_unsigned_bin_size(key.q); mp_to_unsigned_bin(key.q, tmp); fprintf(stderr, "\nq == \n"); for (cnt = 0; cnt < len; ) { fprintf(stderr, "%02x ", tmp[cnt]); if (!(++cnt & 15)) fprintf(stderr, "\n"); } fprintf(stderr, "\n"); return 1; } if (cnt != 9) { rsa_free(&key); } } /* encrypt the key (without lparam) */ for (cnt = 0; cnt < 4; cnt++) { for (rsa_msgsize = 1; rsa_msgsize <= 86; rsa_msgsize++) { /* make a random key/msg */ yarrow_read(in, rsa_msgsize, &yarrow_prng); len = sizeof(out); len2 = rsa_msgsize; DO(rsa_encrypt_key(in, rsa_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, hash_idx, &key)); /* change a byte */ out[8] ^= 1; DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, hash_idx, &stat2, &key)); /* change a byte back */ out[8] ^= 1; if (len2 != rsa_msgsize) { fprintf(stderr, "\nrsa_decrypt_key mismatch len %lu (first decrypt)", len2); return 1; } len2 = rsa_msgsize; DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, hash_idx, &stat, &key)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_decrypt_key failed"); return 1; } if (len2 != rsa_msgsize || memcmp(tmp, in, rsa_msgsize)) { unsigned long x; fprintf(stderr, "\nrsa_decrypt_key mismatch, len %lu (second decrypt)\n", len2); fprintf(stderr, "Original contents: \n"); for (x = 0; x < rsa_msgsize; ) { fprintf(stderr, "%02x ", in[x]); if (!(++x % 16)) { fprintf(stderr, "\n"); } } fprintf(stderr, "\n"); fprintf(stderr, "Output contents: \n"); for (x = 0; x < rsa_msgsize; ) { fprintf(stderr, "%02x ", out[x]); if (!(++x % 16)) { fprintf(stderr, "\n"); } } fprintf(stderr, "\n"); return 1; } } } /* encrypt the key (with lparam) */ for (rsa_msgsize = 1; rsa_msgsize <= 86; rsa_msgsize++) { len = sizeof(out); len2 = rsa_msgsize; DO(rsa_encrypt_key(in, rsa_msgsize, out, &len, lparam, sizeof(lparam), &yarrow_prng, prng_idx, hash_idx, &key)); /* change a byte */ out[8] ^= 1; DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat2, &key)); if (len2 != rsa_msgsize) { fprintf(stderr, "\nrsa_decrypt_key mismatch len %lu (first decrypt)", len2); return 1; } /* change a byte back */ out[8] ^= 1; len2 = rsa_msgsize; DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat, &key)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_decrypt_key failed"); return 1; } if (len2 != rsa_msgsize || memcmp(tmp, in, rsa_msgsize)) { fprintf(stderr, "rsa_decrypt_key mismatch len %lu", len2); return 1; } } /* encrypt the key LTC_PKCS #1 v1.5 (payload from 1 to 117 bytes) */ for (rsa_msgsize = 1; rsa_msgsize <= 117; rsa_msgsize++) { len = sizeof(out); len2 = rsa_msgsize; DO(rsa_encrypt_key_ex(in, rsa_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, 0, LTC_PKCS_1_V1_5, &key)); len2 = rsa_msgsize; DO(rsa_decrypt_key_ex(out, len, tmp, &len2, NULL, 0, 0, LTC_PKCS_1_V1_5, &stat, &key)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_decrypt_key_ex failed, %d, %d", stat, stat2); return 1; } if (len2 != rsa_msgsize || memcmp(tmp, in, rsa_msgsize)) { fprintf(stderr, "rsa_decrypt_key_ex mismatch len %lu", len2); return 1; } } /* sign a message (unsalted, lower cholestorol and Atkins approved) now */ len = sizeof(out); DO(rsa_sign_hash(in, 20, out, &len, &yarrow_prng, prng_idx, hash_idx, 0, &key)); /* export key and import as both private and public */ len2 = sizeof(tmp); DO(rsa_export(tmp, &len2, PK_PRIVATE, &key)); DO(rsa_import(tmp, len2, &privKey)); len2 = sizeof(tmp); DO(rsa_export(tmp, &len2, PK_PUBLIC, &key)); DO(rsa_import(tmp, len2, &pubKey)); /* verify with original */ DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &key)); /* change a byte */ in[0] ^= 1; DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &key)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_verify_hash (unsalted, origKey) failed, %d, %d", stat, stat2); rsa_free(&key); rsa_free(&pubKey); rsa_free(&privKey); return 1; } /* verify with privKey */ /* change a byte */ in[0] ^= 1; DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &privKey)); /* change a byte */ in[0] ^= 1; DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &privKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_verify_hash (unsalted, privKey) failed, %d, %d", stat, stat2); rsa_free(&key); rsa_free(&pubKey); rsa_free(&privKey); return 1; } /* verify with pubKey */ /* change a byte */ in[0] ^= 1; DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &pubKey)); /* change a byte */ in[0] ^= 1; DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &pubKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_verify_hash (unsalted, pubkey) failed, %d, %d", stat, stat2); rsa_free(&key); rsa_free(&pubKey); rsa_free(&privKey); return 1; } /* sign a message (salted) now (use privKey to make, pubKey to verify) */ len = sizeof(out); DO(rsa_sign_hash(in, 20, out, &len, &yarrow_prng, prng_idx, hash_idx, 8, &privKey)); DO(rsa_verify_hash(out, len, in, 20, hash_idx, 8, &stat, &pubKey)); /* change a byte */ in[0] ^= 1; DO(rsa_verify_hash(out, len, in, 20, hash_idx, 8, &stat2, &pubKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_verify_hash (salted) failed, %d, %d", stat, stat2); rsa_free(&key); rsa_free(&pubKey); rsa_free(&privKey); return 1; } /* sign a message with LTC_PKCS #1 v1.5 */ len = sizeof(out); DO(rsa_sign_hash_ex(in, 20, out, &len, LTC_PKCS_1_V1_5, &yarrow_prng, prng_idx, hash_idx, 8, &privKey)); DO(rsa_verify_hash_ex(out, len, in, 20, LTC_PKCS_1_V1_5, hash_idx, 8, &stat, &pubKey)); /* change a byte */ in[0] ^= 1; DO(rsa_verify_hash_ex(out, len, in, 20, LTC_PKCS_1_V1_5, hash_idx, 8, &stat2, &pubKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_verify_hash_ex failed, %d, %d", stat, stat2); rsa_free(&key); rsa_free(&pubKey); rsa_free(&privKey); return 1; } /* free the key and return */ rsa_free(&key); rsa_free(&pubKey); rsa_free(&privKey); return 0; }