Exemplo n.º 1
0
int pn_ssl_get_ssf(pn_ssl_t *ssl0)
{
  const SSL_CIPHER *c;

  pni_ssl_t *ssl = get_ssl_internal(ssl0);
  if (ssl && ssl->ssl && (c = SSL_get_current_cipher( ssl->ssl ))) {
    return SSL_CIPHER_get_bits(c, NULL);
  }
  return 0;
}
Exemplo n.º 2
0
pn_ssl_resume_status_t pn_ssl_resume_status(pn_ssl_t *ssl0)
{
  pni_ssl_t *ssl = get_ssl_internal(ssl0);
  if (!ssl || !ssl->ssl) return PN_SSL_RESUME_UNKNOWN;
  switch (SSL_session_reused( ssl->ssl )) {
  case 0: return PN_SSL_RESUME_NEW;
  case 1: return PN_SSL_RESUME_REUSED;
  default: break;
  }
  return PN_SSL_RESUME_UNKNOWN;
}
Exemplo n.º 3
0
bool pn_ssl_get_protocol_name(pn_ssl_t *ssl0, char *buffer, size_t size )
{
  const SSL_CIPHER *c;

  pni_ssl_t *ssl = get_ssl_internal(ssl0);
  *buffer = '\0';
  if (ssl->ssl && (c = SSL_get_current_cipher( ssl->ssl ))) {
    const char *v = SSL_CIPHER_get_version(c);
    if (v) {
      snprintf( buffer, size, "%s", v );
      return true;
    }
  }
  return false;
}
Exemplo n.º 4
0
const char* pn_ssl_get_remote_subject_subfield(pn_ssl_t *ssl0, pn_ssl_cert_subject_subfield field)
{
    int openssl_field = 0;

    // Assign openssl internal representations of field values to openssl_field
    switch (field) {
        case PN_SSL_CERT_SUBJECT_COUNTRY_NAME :
            openssl_field = NID_countryName;
            break;
        case PN_SSL_CERT_SUBJECT_STATE_OR_PROVINCE :
            openssl_field = NID_stateOrProvinceName;
            break;
        case PN_SSL_CERT_SUBJECT_CITY_OR_LOCALITY :
            openssl_field = NID_localityName;
            break;
        case PN_SSL_CERT_SUBJECT_ORGANIZATION_NAME :
            openssl_field = NID_organizationName;
            break;
        case PN_SSL_CERT_SUBJECT_ORGANIZATION_UNIT :
            openssl_field = NID_organizationalUnitName;
            break;
        case PN_SSL_CERT_SUBJECT_COMMON_NAME :
            openssl_field = NID_commonName;
            break;
        default:
            ssl_log_error("Unknown or unhandled certificate subject subfield %i \n", field);
            return NULL;
    }

    pni_ssl_t *ssl = get_ssl_internal(ssl0);
    X509 *cert = get_peer_certificate(ssl);

    X509_NAME *subject_name = X509_get_subject_name(cert);

    // TODO (gmurthy) - A server side cert subject field can have more than one common name like this - Subject: CN=www.domain1.com, CN=www.domain2.com, see https://bugzilla.mozilla.org/show_bug.cgi?id=380656
    // For now, we will only return the first common name if there is more than one common name in the cert
    int index = X509_NAME_get_index_by_NID(subject_name, openssl_field, -1);

    if (index > -1) {
        X509_NAME_ENTRY *ne = X509_NAME_get_entry(subject_name, index);
        if(ne) {
            ASN1_STRING *name_asn1 = X509_NAME_ENTRY_get_data(ne);
            return (char *) name_asn1->data;
        }
    }

    return NULL;
}
Exemplo n.º 5
0
int pn_ssl_get_peer_hostname(pn_ssl_t *ssl0, char *hostname, size_t *bufsize)
{
  pni_ssl_t *ssl = get_ssl_internal(ssl0);
  if (!ssl) return -1;
  if (!ssl->peer_hostname) {
    *bufsize = 0;
    if (hostname) *hostname = '\0';
    return 0;
  }
  unsigned len = strlen(ssl->peer_hostname);
  if (hostname) {
    if (len >= *bufsize) return -1;
    strcpy( hostname, ssl->peer_hostname );
  }
  *bufsize = len;
  return 0;
}
Exemplo n.º 6
0
int pn_ssl_set_peer_hostname(pn_ssl_t *ssl0, const char *hostname)
{
  pni_ssl_t *ssl = get_ssl_internal(ssl0);
  if (!ssl) return -1;

  if (ssl->peer_hostname) free((void *)ssl->peer_hostname);
  ssl->peer_hostname = NULL;
  if (hostname) {
    ssl->peer_hostname = pn_strdup(hostname);
    if (!ssl->peer_hostname) return -2;
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
    if (ssl->ssl && ssl->domain && ssl->domain->mode == PN_SSL_MODE_CLIENT) {
      SSL_set_tlsext_host_name(ssl->ssl, ssl->peer_hostname);
    }
#endif
  }
  return 0;
}
Exemplo n.º 7
0
const char* pn_ssl_get_remote_subject(pn_ssl_t *ssl0)
{
  pni_ssl_t *ssl = get_ssl_internal(ssl0);
  if (!ssl || !ssl->ssl) return NULL;
  if (!ssl->subject) {
    X509 *cert = SSL_get_peer_certificate(ssl->ssl);
    if (!cert) return NULL;
    X509_NAME *subject = X509_get_subject_name(cert);
    if (!subject) return NULL;

    BIO *out = BIO_new(BIO_s_mem());
    X509_NAME_print_ex(out, subject, 0, XN_FLAG_RFC2253);
    int len = BIO_number_written(out);
    ssl->subject = (char*) malloc(len+1);
    ssl->subject[len] = 0;
    BIO_read(out, ssl->subject, len);
    BIO_free(out);
  }
  return ssl->subject;
}
Exemplo n.º 8
0
int pn_ssl_get_cert_fingerprint(pn_ssl_t *ssl0, char *fingerprint, size_t fingerprint_length, pn_ssl_hash_alg hash_alg)
{
    const char *digest_name = NULL;
    size_t min_required_length;

    // old versions of python expect fingerprint to contain a valid string on
    // return from this function
    fingerprint[0] = 0;

    // Assign the correct digest_name value based on the enum values.
    switch (hash_alg) {
        case PN_SSL_SHA1 :
            min_required_length = 41; // 40 hex characters + 1 '\0' character
            digest_name = "sha1";
            break;
        case PN_SSL_SHA256 :
            min_required_length = 65; // 64 hex characters + 1 '\0' character
            digest_name = "sha256";
            break;
        case PN_SSL_SHA512 :
            min_required_length = 129; // 128 hex characters + 1 '\0' character
            digest_name = "sha512";
            break;
        case PN_SSL_MD5 :
            min_required_length = 33; // 32 hex characters + 1 '\0' character
            digest_name = "md5";
            break;
        default:
            ssl_log_error("Unknown or unhandled hash algorithm %i \n", hash_alg);
            return PN_ERR;

    }

    if(fingerprint_length < min_required_length) {
        ssl_log_error("Insufficient fingerprint_length %i. fingerprint_length must be %i or above for %s digest\n",
            fingerprint_length, min_required_length, digest_name);
        return PN_ERR;
    }

    const EVP_MD  *digest = EVP_get_digestbyname(digest_name);

    pni_ssl_t *ssl = get_ssl_internal(ssl0);

    X509 *cert = get_peer_certificate(ssl);

    if(cert) {
        unsigned int len;

        unsigned char bytes[64]; // sha512 uses 64 octets, we will use that as the maximum.

        if (X509_digest(cert, digest, bytes, &len) != 1) {
            ssl_log_error("Failed to extract X509 digest\n");
            return PN_ERR;
       }

        char *cursor = fingerprint;

        for (size_t i=0; i<len ; i++) {
            cursor +=  snprintf((char *)cursor, fingerprint_length, "%02x", bytes[i]);
            fingerprint_length = fingerprint_length - 2;
        }

        return PN_OK;
    }
    else {
        ssl_log_error("No certificate is available yet \n");
        return PN_ERR;
    }

    return 0;
}