Example #1
0
		inline int compare(const string& lhs, const string& rhs)
		{
#if OPENSSL_VERSION_NUMBER >= 0x01000000
			return ASN1_STRING_cmp(lhs.raw(), rhs.raw());
#else
			return ASN1_STRING_cmp(const_cast<string::pointer>(lhs.raw()), const_cast<string::pointer>(rhs.raw()));
#endif
		}
Example #2
0
static int
OSSL_X509_REVOKED_cmp(const X509_REVOKED * const *a, const X509_REVOKED * const *b)
{
    return(ASN1_STRING_cmp(
		(ASN1_STRING *)(*a)->serialNumber,
		(ASN1_STRING *)(*b)->serialNumber));
}
Example #3
0
static LUA_FUNCTION(openssl_crl_get)
{
  X509_CRL * crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl");
  int i = 0;
  X509_REVOKED *revoked = NULL;
  if (lua_isinteger(L, 2))
  {
    i = lua_tointeger(L, 2);
    luaL_argcheck(L, (i >= 0 && i < sk_X509_REVOKED_num(crl->crl->revoked)), 2, "Out of range");
    revoked = sk_X509_REVOKED_value(crl->crl->revoked, i);
  }
  else
  {
    ASN1_STRING *sn = CHECK_OBJECT(2, ASN1_STRING, "openssl.asn1_integer");
    int cnt = sk_X509_REVOKED_num(crl->crl->revoked);
    for (i = 0; i < cnt; i++)
    {
      X509_REVOKED *rev = sk_X509_REVOKED_value(crl->crl->revoked, i);
      if (ASN1_STRING_cmp(rev->serialNumber, sn) == 0)
      {
        revoked = rev;
        break;
      }
    }
  }
  if (revoked)
  {
    lua_newtable(L);

#if OPENSSL_VERSION_NUMBER > 0x10000000L
    AUXILIAR_SET(L, -1, "code", revoked->reason, number);
    AUXILIAR_SET(L, -1, "reason", openssl_i2s_revoke_reason(revoked->reason), string);
#else
    {
      int crit = 0;
      void* reason = X509_REVOKED_get_ext_d2i(revoked, NID_crl_reason, &crit, NULL);
      AUXILIAR_SET(L, -1, "code", ASN1_ENUMERATED_get(reason), number);
      AUXILIAR_SET(L, -1, "reason", openssl_i2s_revoke_reason(ASN1_ENUMERATED_get(reason)), string);
      ASN1_ENUMERATED_free(reason);
    }
#endif
    PUSH_ASN1_INTEGER(L, revoked->serialNumber);
    lua_setfield(L, -2, "serialNumber");

    PUSH_ASN1_TIME(L, revoked->revocationDate);
    lua_setfield(L, -2, "revocationDate");

    if (crl->crl->extensions)
    {
      lua_pushstring(L, "extensions");
      openssl_sk_x509_extension_totable(L, crl->crl->extensions);
      lua_rawset(L, -3);
    }
  }
  else
    lua_pushnil(L);
  return 1;
}
Example #4
0
static int
pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert)
{
	int ret;

	ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
	    pcert->cert_info->issuer);
	if (ret)
		return ret;
	return ASN1_STRING_cmp(pcert->cert_info->serialNumber,
	    ri->issuer_and_serial->serial);
}
Example #5
0
/**
 * @ingroup proxypolicy
 *
 * Compares two PROXYPOLICY structs for equality
 * This function first compares the policy language numeric
 * id's, if they're equal, it then compares the two policies.
 *
 * @return 0 if equal, nonzero if not
 */
int PROXYPOLICY_cmp(
    const PROXYPOLICY *                 a,
    const PROXYPOLICY *                 b)
{
    
    if((a->policy_language->nid != b->policy_language->nid) ||
       ASN1_STRING_cmp((ASN1_STRING *)a->policy, (ASN1_STRING *)b->policy))
    {
        return 1;
    }
    return 0;
}
Example #6
0
int
X509_issuer_and_serial_cmp(const X509 *a, const X509 *b)
{
	int i;
	X509_CINF *ai, *bi;

	ai = a->cert_info;
	bi = b->cert_info;
	i = ASN1_STRING_cmp(ai->serialNumber, bi->serialNumber);
	if (i)
		return (i);
	return (X509_NAME_cmp(ai->issuer, bi->issuer));
}
Example #7
0
/* Returns 0 if they are equal, != 0 otherwise. */
int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
{
    int result = -1;

    if (!a || !b || a->type != b->type)
        return -1;

    switch (a->type) {
    case V_ASN1_OBJECT:
        result = OBJ_cmp(a->value.object, b->value.object);
        break;
    case V_ASN1_NULL:
        result = 0;             /* They do not have content. */
        break;
    case V_ASN1_BOOLEAN:
        result = a->value.boolean - b->value.boolean;
        break;
    case V_ASN1_INTEGER:
    case V_ASN1_NEG_INTEGER:
    case V_ASN1_ENUMERATED:
    case V_ASN1_NEG_ENUMERATED:
    case V_ASN1_BIT_STRING:
    case V_ASN1_OCTET_STRING:
    case V_ASN1_SEQUENCE:
    case V_ASN1_SET:
    case V_ASN1_NUMERICSTRING:
    case V_ASN1_PRINTABLESTRING:
    case V_ASN1_T61STRING:
    case V_ASN1_VIDEOTEXSTRING:
    case V_ASN1_IA5STRING:
    case V_ASN1_UTCTIME:
    case V_ASN1_GENERALIZEDTIME:
    case V_ASN1_GRAPHICSTRING:
    case V_ASN1_VISIBLESTRING:
    case V_ASN1_GENERALSTRING:
    case V_ASN1_UNIVERSALSTRING:
    case V_ASN1_BMPSTRING:
    case V_ASN1_UTF8STRING:
    case V_ASN1_OTHER:
    default:
        result = ASN1_STRING_cmp((ASN1_STRING *)a->value.ptr,
                                 (ASN1_STRING *)b->value.ptr);
        break;
    }

    return result;
}
Example #8
0
int CPK_MASTER_SECRET_validate_public_params(CPK_MASTER_SECRET *master,
	CPK_PUBLIC_PARAMS *params)
{
	int ret = 0;
	CPK_PUBLIC_PARAMS *tmp = NULL;
	
	if (!(tmp = CPK_MASTER_SECRET_extract_public_params(master))) {
		fprintf(stderr, "shit1\n");
		goto err;
	}	
	if (tmp->version != params->version) {
		fprintf(stderr, "shit2\n");
		goto err;
	}
	if (X509_NAME_cmp(tmp->id, params->id)) {
		fprintf(stderr, "shit3\n");
		goto err;
	}

	/*
	 * two ASN_OBJECT * with different address may have same NID
	 * thus we can not check with:
	 * tmp->pkey_algor->algorithm != params->pkey_algor->algorithm
	 */
	if (OBJ_obj2nid(tmp->pkey_algor->algorithm) != 
	    OBJ_obj2nid(params->pkey_algor->algorithm)) {
		fprintf(stderr, "shit4\n");	
		goto err;
	}
	// FIXME: pkey_algor->parameters
	if (OBJ_obj2nid(tmp->map_algor->algorithm) != 
	    OBJ_obj2nid(params->map_algor->algorithm)) {
		fprintf(stderr, "shit5\n");
		goto err;
	}
	if (ASN1_STRING_cmp(tmp->public_factors, params->public_factors)) {
		fprintf(stderr, "shit6\n");
		goto err;
	}

	ret = 1;
err:
	if (tmp) CPK_PUBLIC_PARAMS_free(tmp);
	return ret;
}
Example #9
0
int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
{
    int neg, ret;
    /* Compare signs */
    neg = x->type & V_ASN1_NEG;
    if (neg != (y->type & V_ASN1_NEG)) {
        if (neg)
            return -1;
        else
            return 1;
    }

    ret = ASN1_STRING_cmp(x, y);

    if (neg)
        return -ret;
    else
        return ret;
}
Example #10
0
/* Returns 0 if they are equal, != 0 otherwise. */
int
GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
{
	int result = -1;

	if (!a || !b || a->type != b->type)
		return -1;
	switch (a->type) {
	case GEN_X400:
	case GEN_EDIPARTY:
		result = ASN1_TYPE_cmp(a->d.other, b->d.other);
		break;

	case GEN_OTHERNAME:
		result = OTHERNAME_cmp(a->d.otherName, b->d.otherName);
		break;

	case GEN_EMAIL:
	case GEN_DNS:
	case GEN_URI:
		result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5);
		break;

	case GEN_DIRNAME:
		result = X509_NAME_cmp(a->d.dirn, b->d.dirn);
		break;

	case GEN_IPADD:
		result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip);
		break;

	case GEN_RID:
		result = OBJ_cmp(a->d.rid, b->d.rid);
		break;
	}
	return result;
}
Example #11
0
bool
ssl_check_certificate (int fd, const char *host)
{
  X509 *cert;
  GENERAL_NAMES *subjectAltNames;
  char common_name[256];
  long vresult;
  bool success = true;
  bool alt_name_checked = false;

  /* If the user has specified --no-check-cert, we still want to warn
     him about problems with the server's certificate.  */
  const char *severity = opt.check_cert ? _("ERROR") : _("WARNING");

  struct openssl_transport_context *ctx = fd_transport_context (fd);
  SSL *conn = ctx->conn;
  assert (conn != NULL);

  cert = SSL_get_peer_certificate (conn);
  if (!cert)
    {
      logprintf (LOG_NOTQUIET, _("%s: No certificate presented by %s.\n"),
                 severity, quotearg_style (escape_quoting_style, host));
      success = false;
      goto no_cert;             /* must bail out since CERT is NULL */
    }

  IF_DEBUG
    {
      char *subject = _get_rfc2253_formatted (X509_get_subject_name (cert));
      char *issuer = _get_rfc2253_formatted (X509_get_issuer_name (cert));
      DEBUGP (("certificate:\n  subject: %s\n  issuer:  %s\n",
               quotearg_n_style (0, escape_quoting_style, subject),
               quotearg_n_style (1, escape_quoting_style, issuer)));
      xfree (subject);
      xfree (issuer);
    }

  vresult = SSL_get_verify_result (conn);
  if (vresult != X509_V_OK)
    {
      char *issuer = _get_rfc2253_formatted (X509_get_issuer_name (cert));
      logprintf (LOG_NOTQUIET,
                 _("%s: cannot verify %s's certificate, issued by %s:\n"),
                 severity, quotearg_n_style (0, escape_quoting_style, host),
                 quote_n (1, issuer));
      xfree(issuer);

      /* Try to print more user-friendly (and translated) messages for
         the frequent verification errors.  */
      switch (vresult)
        {
        case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
          logprintf (LOG_NOTQUIET,
                     _("  Unable to locally verify the issuer's authority.\n"));
          break;
        case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
        case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
          logprintf (LOG_NOTQUIET,
                     _("  Self-signed certificate encountered.\n"));
          break;
        case X509_V_ERR_CERT_NOT_YET_VALID:
          logprintf (LOG_NOTQUIET, _("  Issued certificate not yet valid.\n"));
          break;
        case X509_V_ERR_CERT_HAS_EXPIRED:
          logprintf (LOG_NOTQUIET, _("  Issued certificate has expired.\n"));
          break;
        default:
          /* For the less frequent error strings, simply provide the
             OpenSSL error message.  */
          logprintf (LOG_NOTQUIET, "  %s\n",
                     X509_verify_cert_error_string (vresult));
        }
      success = false;
      /* Fall through, so that the user is warned about *all* issues
         with the cert (important with --no-check-certificate.)  */
    }

  /* Check that HOST matches the common name in the certificate.
     #### The following remains to be done:

     - When matching against common names, it should loop over all
       common names and choose the most specific one, i.e. the last
       one, not the first one, which the current code picks.

     - Ensure that ASN1 strings from the certificate are encoded as
       UTF-8 which can be meaningfully compared to HOST.  */

  subjectAltNames = X509_get_ext_d2i (cert, NID_subject_alt_name, NULL, NULL);

  if (subjectAltNames)
    {
      /* Test subject alternative names */

      /* Do we want to check for dNSNAmes or ipAddresses (see RFC 2818)?
       * Signal it by host_in_octet_string. */
      ASN1_OCTET_STRING *host_in_octet_string = a2i_IPADDRESS (host);

      int numaltnames = sk_GENERAL_NAME_num (subjectAltNames);
      int i;
      for (i=0; i < numaltnames; i++)
        {
          const GENERAL_NAME *name =
            sk_GENERAL_NAME_value (subjectAltNames, i);
          if (name)
            {
              if (host_in_octet_string)
                {
                  if (name->type == GEN_IPADD)
                    {
                      /* Check for ipAddress */
                      /* TODO: Should we convert between IPv4-mapped IPv6
                       * addresses and IPv4 addresses? */
                      alt_name_checked = true;
                      if (!ASN1_STRING_cmp (host_in_octet_string,
                            name->d.iPAddress))
                        break;
                    }
                }
              else if (name->type == GEN_DNS)
                {
                  /* dNSName should be IA5String (i.e. ASCII), however who
                   * does trust CA? Convert it into UTF-8 for sure. */
                  unsigned char *name_in_utf8 = NULL;

                  /* Check for dNSName */
                  alt_name_checked = true;

                  if (0 <= ASN1_STRING_to_UTF8 (&name_in_utf8, name->d.dNSName))
                    {
                      /* Compare and check for NULL attack in ASN1_STRING */
                      if (pattern_match ((char *)name_in_utf8, host) &&
                            (strlen ((char *)name_in_utf8) ==
                                (size_t) ASN1_STRING_length (name->d.dNSName)))
                        {
                          OPENSSL_free (name_in_utf8);
                          break;
                        }
                      OPENSSL_free (name_in_utf8);
                    }
                }
            }
        }
      sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
      if (host_in_octet_string)
        ASN1_OCTET_STRING_free(host_in_octet_string);

      if (alt_name_checked == true && i >= numaltnames)
        {
          logprintf (LOG_NOTQUIET,
              _("%s: no certificate subject alternative name matches\n"
                "\trequested host name %s.\n"),
                     severity, quote_n (1, host));
          success = false;
        }
    }

  if (alt_name_checked == false)
    {
      /* Test commomName */
      X509_NAME *xname = X509_get_subject_name(cert);
      common_name[0] = '\0';
      X509_NAME_get_text_by_NID (xname, NID_commonName, common_name,
                                 sizeof (common_name));

      if (!pattern_match (common_name, host))
        {
          logprintf (LOG_NOTQUIET, _("\
    %s: certificate common name %s doesn't match requested host name %s.\n"),
                     severity, quote_n (0, common_name), quote_n (1, host));
          success = false;
        }
Example #12
0
/* Confirm the peer identity, by checking if the certificate subject 
 * matches the peer's DNS name or IP address. Matching is performed in
 * accordance with RFC 2818:
 *
 * If the certificate has a subjectAltName extension, all names of type
 * IPAddress or dnsName present there, will be compared to data->host,
 * depending on it's contents.
 * In case there's no subjectAltName extension, commonName (CN) parts
 * of the certificate subject field will be used instead of IPAddress
 * and dnsName entries. For IP addresses, common names must contain IPs
 * in presentation format (1.2.3.4 or 2001:DB8:15:dead::)
 * Finally, if no subjectAltName or common names are present, the
 * certificate is considered to not match the peer.
 *
 * The structure of X509 certificates and all fields referenced above
 * are described in RFC 5280.
 *
 * The certificate must be pointed by cert and the peer's host must be
 * placed in data->host. The format is a regular DNS name or an IP in
 * presentation format (see above).
 * 
 * Return value: 1 if the certificate matches the peer, 0 otherwise.
 */
static int ssl_verifycn(X509 *cert, ssl_appdata *data)
{
  char *cn;
  int crit = 0, match = 0;
  ASN1_OCTET_STRING *ip;
  GENERAL_NAMES *altname; /* SubjectAltName ::= GeneralNames */
  
  ip = a2i_IPADDRESS(data->host); /* check if it's an IP or a hostname */
  if ((altname = X509_get_ext_d2i(cert, NID_subject_alt_name, &crit, NULL))) {
    GENERAL_NAME *gn;

    /* Loop through the general names in altname and pick these
       of type ip address or dns name */
    while (!match && (gn = sk_GENERAL_NAME_pop(altname))) {
      /* if the peer's host is an IP, we're only interested in
         matching against iPAddress general names, otherwise
         we'll only look for dnsName's */
      if (ip) {
        if (gn->type == GEN_IPADD)
          match = !ASN1_STRING_cmp(gn->d.ip, ip);
      } else if (gn->type == GEN_DNS) {
        /* IA5string holds ASCII data */
        cn = (char *) ASN1_STRING_data(gn->d.ia5);
        match = ssl_hostmatch(cn, data->host);
      }
    }
    sk_GENERAL_NAME_free(altname);
  } else { /* no subjectAltName, try to match against the subject CNs */
    X509_NAME *subj; /* certificate subject */

    /* the following is just for information */
    switch (crit) {
      case 0:
        debug0("TLS: X509 subjectAltName cannot be decoded");
        break;
      case -1:
        debug0("TLS: X509 has no subjectAltName extension");
        break;
      case -2:
        debug0("TLS: X509 has multiple subjectAltName extensions");
    }
    /* no subject name either? A completely broken certificate :) */
    if (!(subj = X509_get_subject_name(cert))) {
      putlog(data->loglevel, "*", "TLS: peer certificate has no subject: %s",
             data->host);
      match = 0;
    } else { /* we have a subject name, look at it */
      int pos = -1;
      ASN1_STRING *name;
      
      /* Look for commonName attributes in the subject name */
      pos = X509_NAME_get_index_by_NID(subj, NID_commonName, pos);
      if (pos == -1) /* sorry */
        putlog(data->loglevel, "*", "TLS: Peer has no common names and "
              "no subjectAltName extension. Verification failed.");
      /* Loop through all common names which may be present in the subject
         name until we find a match. */
      while (!match && pos != -1) {
        name = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subj, pos));
        cn = (char *) ASN1_STRING_data(name);
        if (ip)
          match = a2i_IPADDRESS(cn) ? (ASN1_STRING_cmp(ip, a2i_IPADDRESS(cn)) ? 0 : 1) : 0;
        else
          match = ssl_hostmatch(cn, data->host);
        pos = X509_NAME_get_index_by_NID(subj, NID_commonName, pos);
      }
    }
  }

  if (ip)
    ASN1_OCTET_STRING_free(ip);
  return match;
}