Commit 9c3fba5c authored by Nick Mathewson's avatar Nick Mathewson 🐚
Browse files

Not every RSA decrypt should warn on failure.


svn:r1853
parent f1bc7af9
Loading
Loading
Loading
Loading
+8 −9
Original line number Diff line number Diff line
@@ -534,7 +534,7 @@ int crypto_pk_public_encrypt(crypto_pk_env_t *env, const unsigned char *from, in
 * write the result to <b>to</b>, and return the number of bytes
 * written.  On failure, return -1.
 */
int crypto_pk_private_decrypt(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to, int padding)
int crypto_pk_private_decrypt(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to, int padding, int warnOnFailure)
{
  int r;
  tor_assert(env && from && to && env->key);
@@ -545,7 +545,8 @@ int crypto_pk_private_decrypt(crypto_pk_env_t *env, const unsigned char *from, i
  r = RSA_private_decrypt(fromlen, (unsigned char*)from, to, env->key,
                             crypto_get_rsa_padding(padding));
  if (r<0) {
    crypto_log_errors(LOG_WARN, "performing RSA decryption");
    crypto_log_errors(warnOnFailure?LOG_WARN:LOG_INFO,
                      "performing RSA decryption");
    return -1;
  }
  return r;
@@ -714,7 +715,7 @@ int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env,
int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env,
                                     const unsigned char *from,
                                     int fromlen, unsigned char *to,
                                     int padding)
                                     int padding, int warnOnFailure)
{
  int overhead, pkeylen, outlen, r;
  crypto_cipher_env_t *cipher = NULL;
@@ -724,17 +725,15 @@ int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env,
  pkeylen = crypto_pk_keysize(env);

  if (fromlen <= pkeylen) {
    return crypto_pk_private_decrypt(env,from,fromlen,to,padding);
    return crypto_pk_private_decrypt(env,from,fromlen,to,padding,warnOnFailure);
  }
  outlen = crypto_pk_private_decrypt(env,from,pkeylen,buf,padding);
  outlen = crypto_pk_private_decrypt(env,from,pkeylen,buf,padding,warnOnFailure);
  if (outlen<0) {
    /* this is only log-levelinfo, because when we're decrypting
     * onions, we try several keys to see which will work */
    log_fn(LOG_INFO, "Error decrypting public-key data");
    log_fn(warnOnFailure?LOG_WARN:LOG_INFO, "Error decrypting public-key data");
    return -1;
  }
  if (outlen < CIPHER_KEY_LEN) {
    log_fn(LOG_WARN, "No room for a symmetric key");
    log_fn(warnOnFailure?LOG_WARN:LOG_INFO, "No room for a symmetric key");
    return -1;
  }
  cipher = crypto_create_init_cipher(buf, 0);
+3 −2
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ crypto_pk_env_t *crypto_pk_dup_key(crypto_pk_env_t *orig);
int crypto_pk_keysize(crypto_pk_env_t *env);

int crypto_pk_public_encrypt(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to, int padding);
int crypto_pk_private_decrypt(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to, int padding);
int crypto_pk_private_decrypt(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to, int padding, int warnOnFailure);
int crypto_pk_private_sign(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to);
int crypto_pk_private_sign_digest(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to);
int crypto_pk_public_checksig(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to);
@@ -78,7 +78,8 @@ int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env,
                                    unsigned char *to, int padding, int force);
int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env,
                                     const unsigned char *from, int fromlen,
                                     unsigned char *to,int padding);
                                     unsigned char *to,int padding,
                                     int warnOnFailure);

int crypto_pk_asn1_encode(crypto_pk_env_t *pk, char *dest, int dest_len);
crypto_pk_env_t *crypto_pk_asn1_decode(const char *str, int len);
+2 −2
Original line number Diff line number Diff line
@@ -728,12 +728,12 @@ onion_skin_server_handshake(char *onion_skin, /* ONIONSKIN_CHALLENGE_LEN bytes *
      break;
    len = crypto_pk_private_hybrid_decrypt(k,
                                           onion_skin, ONIONSKIN_CHALLENGE_LEN,
                                           challenge, PK_PKCS1_OAEP_PADDING);
                                           challenge, PK_PKCS1_OAEP_PADDING,0);
    if (len>0)
      break;
  }
  if (len<0) {
    log_fn(LOG_WARN, "Couldn't decrypt onionskin");
    log_fn(LOG_WARN, "Couldn't decrypt onionskin: client may be using old onion key");
    goto err;
  } else if (len != DH_KEY_LEN) {
    log_fn(LOG_WARN, "Unexpected onionskin length after decryption: %d",
+1 −1
Original line number Diff line number Diff line
@@ -388,7 +388,7 @@ rend_service_introduce(circuit_t *circuit, const char *request, int request_len)
  /* Next N bytes is encrypted with service key */
  len = crypto_pk_private_hybrid_decrypt(
       service->private_key,request+DIGEST_LEN,request_len-DIGEST_LEN,buf,
       PK_PKCS1_OAEP_PADDING);
       PK_PKCS1_OAEP_PADDING,1);
  if (len<0) {
    log_fn(LOG_WARN, "Couldn't decrypt INTRODUCE2 cell");
    return -1;
+6 −6
Original line number Diff line number Diff line
@@ -333,19 +333,19 @@ test_crypto()
  /* oaep padding should make encryption not match */
  test_memneq(data1, data2, 128);
  test_eq(15, crypto_pk_private_decrypt(pk1, data1, 128, data3,
                                        PK_PKCS1_OAEP_PADDING));
                                        PK_PKCS1_OAEP_PADDING,1));
  test_streq(data3, "Hello whirled.");
  memset(data3, 0, 1024);
  test_eq(15, crypto_pk_private_decrypt(pk1, data2, 128, data3,
                                        PK_PKCS1_OAEP_PADDING));
                                        PK_PKCS1_OAEP_PADDING,1));
  test_streq(data3, "Hello whirled.");
  /* Can't decrypt with public key. */
  test_eq(-1, crypto_pk_private_decrypt(pk2, data2, 128, data3,
                                        PK_PKCS1_OAEP_PADDING));
                                        PK_PKCS1_OAEP_PADDING,1));
  /* Try again with bad padding */
  memcpy(data2+1, "XYZZY", 5);  /* This has fails ~ once-in-2^40 */
  test_eq(-1, crypto_pk_private_decrypt(pk1, data2, 128, data3,
                                        PK_PKCS1_OAEP_PADDING));
                                        PK_PKCS1_OAEP_PADDING,1));

  /* File operations: save and load private key */
  test_assert(! crypto_pk_write_private_key_to_filename(pk1,
@@ -354,7 +354,7 @@ test_crypto()
  test_assert(! crypto_pk_read_private_key_from_filename(pk2,
                                                  "/tmp/tor_test/pke1y"));
  test_eq(15, crypto_pk_private_decrypt(pk2, data1, 128, data3,
                                        PK_PKCS1_OAEP_PADDING));
                                        PK_PKCS1_OAEP_PADDING,1));

  /* Now try signing. */
  strcpy(data1, "Ossifrage");
@@ -388,7 +388,7 @@ test_crypto()
        (i==1)?PK_PKCS1_PADDING:PK_PKCS1_OAEP_PADDING;
      len = crypto_pk_public_hybrid_encrypt(pk1,data1,j,data2,p,0);
      test_assert(len>=0);
      len = crypto_pk_private_hybrid_decrypt(pk1,data2,len,data3,p);
      len = crypto_pk_private_hybrid_decrypt(pk1,data2,len,data3,p,1);
      test_eq(len,j);
      test_memeq(data1,data3,j);
    }