Commit aaaf082e authored by Nick Mathewson's avatar Nick Mathewson 🦀
Browse files

Merge remote-tracking branch 'majek/bug5170'

parents c300720b d769cd82
Loading
Loading
Loading
Loading

changes/bug5170

0 → 100644
+5 −0
Original line number Diff line number Diff line
  o Code simplification and refactoring:
    - Remove contrib/id_to_fp.c since it wasn't used anywhere.
    - Since OpenSSL 0.9.7 i2d_* functions support allocating output
      buffer. Avoid calling twice: i2d_RSAPublicKey, i2d_DHparams,
      i2d_X509, i2d_PublicKey. Fixes #5170.

contrib/id_to_fp.c

deleted100644 → 0
+0 −77
Original line number Diff line number Diff line
/* Copyright 2006 Nick Mathewson; see LICENSE for licensing information */

/* id_to_fp.c : Helper for directory authority ops.  When somebody sends us
 * a private key, this utility converts the private key into a fingerprint
 * so you can de-list that fingerprint.
 */

#include <openssl/rsa.h>
#include <openssl/bio.h>
#include <openssl/sha.h>
#include <openssl/pem.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define die(s) do { fprintf(stderr, "%s\n", s); goto err; } while (0)

int
main(int argc, char **argv)
{
  BIO *b = NULL;
  RSA *key = NULL;
  unsigned char *buf = NULL, *bufp;
  int len, i;
  unsigned char digest[20];
  int status = 1;

  if (argc < 2) {
    fprintf(stderr, "Reading key from stdin...\n");
    if (!(b = BIO_new_fp(stdin, BIO_NOCLOSE)))
      die("couldn't read from stdin");
  } else if (argc == 2) {
    if (strcmp(argv[1], "-h") == 0 ||
        strcmp(argv[1], "--help") == 0) {
      fprintf(stdout, "Usage: %s [keyfile]\n", argv[0]);
      status = 0;
      goto err;
    } else {
      if (!(b = BIO_new_file(argv[1], "r")))
        die("couldn't open file");
    }
  } else {
    fprintf(stderr, "Usage: %s [keyfile]\n", argv[0]);
    goto err;
  }
  if (!(key = PEM_read_bio_RSAPrivateKey(b, NULL, NULL, NULL)))
    die("couldn't parse key");

  len = i2d_RSAPublicKey(key, NULL);
  if (len < 0)
    die("Bizarre key");
  bufp = buf = malloc(len+1);
  if (!buf)
    die("Out of memory");
  len = i2d_RSAPublicKey(key, &bufp);
  if (len < 0)
    die("Bizarre key");

  SHA1(buf, len, digest);
  for (i=0; i < 20; i += 2) {
    printf("%02X%02X ", (int)digest[i], (int)digest[i+1]);
  }
  printf("\n");

  status = 0;

err:
  if (buf)
    free(buf);
  if (key)
    RSA_free(key);
  if (b)
    BIO_free(b);
  return status;
}
+22 −44
Original line number Diff line number Diff line
@@ -1152,22 +1152,21 @@ int
crypto_pk_asn1_encode(crypto_pk_t *pk, char *dest, size_t dest_len)
{
  int len;
  unsigned char *buf, *cp;
  len = i2d_RSAPublicKey(pk->key, NULL);
  if (len < 0 || (size_t)len > dest_len || dest_len > SIZE_T_CEILING)
  unsigned char *buf = NULL;

  len = i2d_RSAPublicKey(pk->key, &buf);
  if (len < 0 || buf == NULL)
    return -1;
  cp = buf = tor_malloc(len+1);
  len = i2d_RSAPublicKey(pk->key, &cp);
  if (len < 0) {
    crypto_log_errors(LOG_WARN,"encoding public key");
    tor_free(buf);

  if ((size_t)len > dest_len || dest_len > SIZE_T_CEILING) {
    OPENSSL_free(buf);
    return -1;
  }
  /* We don't encode directly into 'dest', because that would be illegal
   * type-punning.  (C99 is smarter than me, C99 is smarter than me...)
   */
  memcpy(dest,buf,len);
  tor_free(buf);
  OPENSSL_free(buf);
  return len;
}

@@ -1198,24 +1197,17 @@ crypto_pk_asn1_decode(const char *str, size_t len)
int
crypto_pk_get_digest(crypto_pk_t *pk, char *digest_out)
{
  unsigned char *buf, *bufp;
  unsigned char *buf = NULL;
  int len;

  len = i2d_RSAPublicKey(pk->key, NULL);
  if (len < 0)
  len = i2d_RSAPublicKey(pk->key, &buf);
  if (len < 0 || buf == NULL)
    return -1;
  buf = bufp = tor_malloc(len+1);
  len = i2d_RSAPublicKey(pk->key, &bufp);
  if (len < 0) {
    crypto_log_errors(LOG_WARN,"encoding public key");
    tor_free(buf);
    return -1;
  }
  if (crypto_digest(digest_out, (char*)buf, len) < 0) {
    tor_free(buf);
    OPENSSL_free(buf);
    return -1;
  }
  tor_free(buf);
  OPENSSL_free(buf);
  return 0;
}

@@ -1224,24 +1216,17 @@ crypto_pk_get_digest(crypto_pk_t *pk, char *digest_out)
int
crypto_pk_get_all_digests(crypto_pk_t *pk, digests_t *digests_out)
{
  unsigned char *buf, *bufp;
  unsigned char *buf = NULL;
  int len;

  len = i2d_RSAPublicKey(pk->key, NULL);
  if (len < 0)
  len = i2d_RSAPublicKey(pk->key, &buf);
  if (len < 0 || buf == NULL)
    return -1;
  buf = bufp = tor_malloc(len+1);
  len = i2d_RSAPublicKey(pk->key, &bufp);
  if (len < 0) {
    crypto_log_errors(LOG_WARN,"encoding public key");
    tor_free(buf);
    return -1;
  }
  if (crypto_digest_all(digests_out, (char*)buf, len) < 0) {
    tor_free(buf);
    OPENSSL_free(buf);
    return -1;
  }
  tor_free(buf);
  OPENSSL_free(buf);
  return 0;
}

@@ -1703,7 +1688,7 @@ crypto_store_dynamic_dh_modulus(const char *fname)
{
  int len, new_len;
  DH *dh = NULL;
  unsigned char *dh_string_repr = NULL, *cp = NULL;
  unsigned char *dh_string_repr = NULL;
  char *base64_encoded_dh = NULL;
  char *file_string = NULL;
  int retval = -1;
@@ -1727,15 +1712,8 @@ crypto_store_dynamic_dh_modulus(const char *fname)
  if (!BN_set_word(dh->g, DH_GENERATOR))
    goto done;

  len = i2d_DHparams(dh, NULL);
  if (len < 0) {
    log_warn(LD_CRYPTO, "Error occured while DER encoding DH modulus (1).");
    goto done;
  }

  cp = dh_string_repr = tor_malloc_zero(len+1);
  len = i2d_DHparams(dh, &cp);
  if ((len < 0) || ((cp - dh_string_repr) != len)) {
  len = i2d_DHparams(dh, &dh_string_repr);
  if ((len < 0) || (dh_string_repr == NULL)) {
    log_warn(LD_CRYPTO, "Error occured while DER encoding DH modulus (2).");
    goto done;
  }
@@ -1762,7 +1740,7 @@ crypto_store_dynamic_dh_modulus(const char *fname)
 done:
  if (dh)
    DH_free(dh);
  tor_free(dh_string_repr);
  OPENSSL_free(dh_string_repr);
  tor_free(base64_encoded_dh);
  tor_free(file_string);

+23 −25
Original line number Diff line number Diff line
@@ -806,24 +806,24 @@ tor_cert_new(X509 *x509_cert)
  tor_cert_t *cert;
  EVP_PKEY *pkey;
  RSA *rsa;
  int length, length2;
  unsigned char *cp;
  int length;
  unsigned char *buf = NULL;

  if (!x509_cert)
    return NULL;

  length = i2d_X509(x509_cert, NULL);
  length = i2d_X509(x509_cert, &buf);
  cert = tor_malloc_zero(sizeof(tor_cert_t));
  if (length <= 0) {
  if (length <= 0 || buf == NULL) {
    tor_free(cert);
    log_err(LD_CRYPTO, "Couldn't get length of encoded x509 certificate");
    X509_free(x509_cert);
    return NULL;
  }
  cert->encoded_len = (size_t) length;
  cp = cert->encoded = tor_malloc(length);
  length2 = i2d_X509(x509_cert, &cp);
  tor_assert(length2 == length);
  cert->encoded = tor_malloc(length);
  memcpy(cert->encoded, buf, length);
  OPENSSL_free(buf);

  cert->cert = x509_cert;

@@ -980,27 +980,25 @@ tor_tls_cert_get_key(tor_cert_t *cert)
}

/** Return true iff <b>a</b> and <b>b</b> represent the same public key. */
static int
pkey_eq(EVP_PKEY *a, EVP_PKEY *b)
int
tor_tls_evp_pkey_eq(EVP_PKEY *a, EVP_PKEY *b)
{
  /* We'd like to do this, but openssl 0.9.7 doesn't have it:
     return EVP_PKEY_cmp(a,b) == 1;
  */
  unsigned char *a_enc=NULL, *b_enc=NULL, *a_ptr, *b_ptr;
  int a_len1, b_len1, a_len2, b_len2, result;
  a_len1 = i2d_PublicKey(a, NULL);
  b_len1 = i2d_PublicKey(b, NULL);
  if (a_len1 != b_len1)
    return 0;
  a_ptr = a_enc = tor_malloc(a_len1);
  b_ptr = b_enc = tor_malloc(b_len1);
  a_len2 = i2d_PublicKey(a, &a_ptr);
  b_len2 = i2d_PublicKey(b, &b_ptr);
  tor_assert(a_len2 == a_len1);
  tor_assert(b_len2 == b_len1);
  result = tor_memeq(a_enc, b_enc, a_len1);
  tor_free(a_enc);
  tor_free(b_enc);
  unsigned char *a_enc = NULL, *b_enc = NULL;
  int a_len, b_len, result;
  a_len = i2d_PublicKey(a, &a_enc);
  b_len = i2d_PublicKey(b, &b_enc);
  if (a_len != b_len || a_len < 0) {
    result = 0;
  } else {
    result = tor_memeq(a_enc, b_enc, a_len);
  }
  if (a_enc)
    OPENSSL_free(a_enc);
  if (b_enc)
    OPENSSL_free(b_enc);
  return result;
}

@@ -1019,7 +1017,7 @@ tor_tls_cert_matches_key(const tor_tls_t *tls, const tor_cert_t *cert)
  link_key = X509_get_pubkey(peercert);
  cert_key = X509_get_pubkey(cert->cert);

  result = link_key && cert_key && pkey_eq(cert_key, link_key);
  result = link_key && cert_key && tor_tls_evp_pkey_eq(cert_key, link_key);

  X509_free(peercert);
  if (link_key)
+5 −0
Original line number Diff line number Diff line
@@ -138,5 +138,10 @@ int tor_tls_cert_is_valid(int severity,
                          int check_rsa_1024);
const char *tor_tls_get_ciphersuite_name(tor_tls_t *tls);

#ifdef TORTLS_PRIVATE
/* Prototypes for private functions only used by the unit tests. */
int tor_tls_evp_pkey_eq(EVP_PKEY *a, EVP_PKEY *b);
#endif

#endif
Loading