Beispiel #1
0
/*
 * Whack an ASIdentifierChoice into canonical form.
 */
static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
{
  ASN1_INTEGER *a_max_plus_one = NULL;
  BIGNUM *bn = NULL;
  int i, ret = 0;

  /*
   * Nothing to do for empty element or inheritance.
   */
  if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
    return 1;

  /*
   * If not a list, or if empty list, it's broken.
   */
  if (choice->type != ASIdentifierChoice_asIdsOrRanges ||
      sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) {
    X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
	      X509V3_R_EXTENSION_VALUE_ERROR);
    return 0;
  }

  /*
   * We have a non-empty list.  Sort it.
   */
  sk_ASIdOrRange_sort(choice->u.asIdsOrRanges);

  /*
   * Now check for errors and suboptimal encoding, rejecting the
   * former and fixing the latter.
   */
  for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
    ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
    ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1);
    ASN1_INTEGER *a_min, *a_max, *b_min, *b_max;

    extract_min_max(a, &a_min, &a_max);
    extract_min_max(b, &b_min, &b_max);

    /*
     * Make sure we're properly sorted (paranoia).
     */
    OPENSSL_assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0);

    /*
     * Punt inverted ranges.
     */
    if (ASN1_INTEGER_cmp(a_min, a_max) > 0 ||
	ASN1_INTEGER_cmp(b_min, b_max) > 0)
      goto done;

    /*
     * Check for overlaps.
     */
    if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) {
      X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
		X509V3_R_EXTENSION_VALUE_ERROR);
      goto done;
    }

    /*
     * Calculate a_max + 1 to check for adjacency.
     */
    if ((bn == NULL && (bn = BN_new()) == NULL) ||
	ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
	!BN_add_word(bn, 1) ||
	(a_max_plus_one = BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) {
      X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, ERR_R_MALLOC_FAILURE);
      goto done;
    }
    
    /*
     * If a and b are adjacent, merge them.
     */
    if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) {
      ASRange *r;
      switch (a->type) {
      case ASIdOrRange_id:
	if ((r = OPENSSL_malloc(sizeof(ASRange))) == NULL) {
	  X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
		    ERR_R_MALLOC_FAILURE);
	  goto done;
	}
	r->min = a_min;
	r->max = b_max;
	a->type = ASIdOrRange_range;
	a->u.range = r;
	break;
      case ASIdOrRange_range:
	ASN1_INTEGER_free(a->u.range->max);
	a->u.range->max = b_max;
	break;
      }
      switch (b->type) {
      case ASIdOrRange_id:
	b->u.id = NULL;
	break;
      case ASIdOrRange_range:
	b->u.range->max = NULL;
	break;
      }
      ASIdOrRange_free(b);
      (void) sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1);
      i--;
      continue;
    }
  }

  /*
   * Check for final inverted range.
   */
  i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1;
  {
    ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
    ASN1_INTEGER *a_min, *a_max;
    if (a != NULL && a->type == ASIdOrRange_range) {
      extract_min_max(a, &a_min, &a_max);
      if (ASN1_INTEGER_cmp(a_min, a_max) > 0)
	goto done;
    }
  }

  OPENSSL_assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */

  ret = 1;

 done:
  ASN1_INTEGER_free(a_max_plus_one);
  BN_free(bn);
  return ret;
}
Beispiel #2
0
/*
 * Check whether an ASIdentifierChoice is in canonical form.
 */
static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice)
{
  ASN1_INTEGER *a_max_plus_one = NULL;
  BIGNUM *bn = NULL;
  int i, ret = 0;

  /*
   * Empty element or inheritance is canonical.
   */
  if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
    return 1;

  /*
   * If not a list, or if empty list, it's broken.
   */
  if (choice->type != ASIdentifierChoice_asIdsOrRanges ||
      sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0)
    return 0;

  /*
   * It's a list, check it.
   */
  for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
    ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
    ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1);
    ASN1_INTEGER *a_min, *a_max, *b_min, *b_max;

    extract_min_max(a, &a_min, &a_max);
    extract_min_max(b, &b_min, &b_max);

    /*
     * Punt misordered list, overlapping start, or inverted range.
     */
    if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 ||
	ASN1_INTEGER_cmp(a_min, a_max) > 0 ||
	ASN1_INTEGER_cmp(b_min, b_max) > 0)
      goto done;

    /*
     * Calculate a_max + 1 to check for adjacency.
     */
    if ((bn == NULL && (bn = BN_new()) == NULL) ||
	ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
	!BN_add_word(bn, 1) ||
	(a_max_plus_one = BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) {
      X509V3err(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL,
		ERR_R_MALLOC_FAILURE);
      goto done;
    }
    
    /*
     * Punt if adjacent or overlapping.
     */
    if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0)
      goto done;
  }

  /*
   * Check for inverted range.
   */
  i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1;
  {
    ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
    ASN1_INTEGER *a_min, *a_max;
    if (a != NULL && a->type == ASIdOrRange_range) {
      extract_min_max(a, &a_min, &a_max);
      if (ASN1_INTEGER_cmp(a_min, a_max) > 0)
	goto done;
    }
  }

  ret = 1;

 done:
  ASN1_INTEGER_free(a_max_plus_one);
  BN_free(bn);
  return ret;
}
Beispiel #3
0
bool a1int::operator != (const a1int &a) const
{
	return (ASN1_INTEGER_cmp(in, a.in) != 0);
}
Beispiel #4
0
/* based on BSD-style licensed code of mod_ssl */
static int crl_check(CLI *c, X509_STORE_CTX *callback_ctx) {
    X509_STORE_CTX store_ctx;
    X509_OBJECT obj;
    X509_NAME *subject;
    X509_NAME *issuer;
    X509 *cert;
    X509_CRL *crl;
    X509_REVOKED *revoked;
    EVP_PKEY *pubkey;
    long serial;
    int i, n, rc;
    char *cp;
    ASN1_TIME *last_update=NULL, *next_update=NULL;

    /* determine certificate ingredients in advance */
    cert=X509_STORE_CTX_get_current_cert(callback_ctx);
    subject=X509_get_subject_name(cert);
    issuer=X509_get_issuer_name(cert);

    /* try to retrieve a CRL corresponding to the _subject_ of
     * the current certificate in order to verify it's integrity */
    memset((char *)&obj, 0, sizeof obj);
    X509_STORE_CTX_init(&store_ctx, c->opt->revocation_store, NULL, NULL);
    rc=X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, subject, &obj);
    X509_STORE_CTX_cleanup(&store_ctx);
    crl=obj.data.crl;
    if(rc>0 && crl) {
        cp=X509_NAME_oneline(subject, NULL, 0);
        s_log(LOG_INFO, "CRL: issuer: %s", cp);
        OPENSSL_free(cp);
        last_update=X509_CRL_get_lastUpdate(crl);
        next_update=X509_CRL_get_nextUpdate(crl);
        log_time(LOG_INFO, "CRL: last update", last_update);
        log_time(LOG_INFO, "CRL: next update", next_update);

        /* verify the signature on this CRL */
        pubkey=X509_get_pubkey(cert);
        if(X509_CRL_verify(crl, pubkey)<=0) {
            s_log(LOG_WARNING, "CRL: Invalid signature");
            X509_STORE_CTX_set_error(callback_ctx,
                X509_V_ERR_CRL_SIGNATURE_FAILURE);
            X509_OBJECT_free_contents(&obj);
            if(pubkey)
                EVP_PKEY_free(pubkey);
            return 0; /* reject connection */
        }
        if(pubkey)
            EVP_PKEY_free(pubkey);

        /* check date of CRL to make sure it's not expired */
        if(!next_update) {
            s_log(LOG_WARNING, "CRL: Invalid nextUpdate field");
            X509_STORE_CTX_set_error(callback_ctx,
                X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);
            X509_OBJECT_free_contents(&obj);
            return 0; /* reject connection */
        }
        if(X509_cmp_current_time(next_update)<0) {
            s_log(LOG_WARNING, "CRL: CRL Expired - revoking all certificates");
            X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CRL_HAS_EXPIRED);
            X509_OBJECT_free_contents(&obj);
            return 0; /* reject connection */
        }
        X509_OBJECT_free_contents(&obj);
    }

    /* try to retrieve a CRL corresponding to the _issuer_ of
     * the current certificate in order to check for revocation */
    memset((char *)&obj, 0, sizeof obj);
    X509_STORE_CTX_init(&store_ctx, c->opt->revocation_store, NULL, NULL);
    rc=X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, issuer, &obj);
    X509_STORE_CTX_cleanup(&store_ctx);
    crl=obj.data.crl;
    if(rc>0 && crl) {
        /* check if the current certificate is revoked by this CRL */
        n=sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
        for(i=0; i<n; i++) {
            revoked=sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
            if(ASN1_INTEGER_cmp(revoked->serialNumber,
                    X509_get_serialNumber(cert)) == 0) {
                serial=ASN1_INTEGER_get(revoked->serialNumber);
                cp=X509_NAME_oneline(issuer, NULL, 0);
                s_log(LOG_WARNING, "CRL: Certificate with serial %ld (0x%lX) "
                    "revoked per CRL from issuer %s", serial, serial, cp);
                OPENSSL_free(cp);
                X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CERT_REVOKED);
                X509_OBJECT_free_contents(&obj);
                return 0; /* reject connection */
            }
        }
        X509_OBJECT_free_contents(&obj);
    }
    return 1; /* accept connection */
}
Beispiel #5
0
const PKI_X509_CRL_ENTRY * PKI_X509_CRL_lookup(const PKI_X509_CRL *x, 
                 const PKI_INTEGER *s ) {

  long long end = 0;
  const STACK_OF(X509_REVOKED) * r_sk = NULL;

  X509_CRL *crl = NULL;

  // Input Checks
  if (!x || !s) return (NULL);

  // Gets the revoked stack
  if ((r_sk = X509_CRL_get_REVOKED(crl)) == NULL) {
    // No Entries in the CRL
    return NULL;
  }

  /* Set the end point to the last one */
  if ((end = (long long) sk_X509_REVOKED_num(r_sk) - 1) < 0)
    return NULL;

  // Gets a casted pointer
  crl = (X509_CRL *) x;

        /* Look for serial number of certificate in CRL */
        // rtmp.serialNumber = (ASN1_INTEGER *) serial;
        // ok = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp);

#if OPENSSL_VERSION_NUMBER >= 0x1010000fL

  PKI_X509_CRL_ENTRY *r = NULL;

  // Gets the reference in r
  X509_CRL_get0_by_serial(crl, &r, (PKI_INTEGER *)s);

#else

  long long curr = 0;
  long long cmp_val = 0;

  const PKI_X509_CRL_ENTRY *r = NULL;

  for( curr = 0 ; curr <= end ; curr++ ) {
 
    const PKI_X509_CRL_ENTRY *r = NULL;
    const PKI_INTEGER * s_pnt;
      // Pointer to the SN in the X509_REVOKED struct

    // Gets the X509_REVOKED entry
    if ((r = sk_X509_REVOKED_value( r_sk, (int) curr )) != NULL) {


// # if OPENSSL_VERSION_NUMBER >= 0x1010000fL
//       // Gets the Serial Number
//       if ((s_pnt = X509_REVOKED_get0_serialNumber(r)) != NULL) {
//         // Checks the value against the CRL
//         if ((cmp_val = ASN1_INTEGER_cmp(s_pnt, s)) == 0) {
//           // Found
//           break;
//         }
//       }
// # else
      if ((s_pnt = r->serialNumber) != NULL) {
        // Checks the value against the CRL
        if ((cmp_val = ASN1_INTEGER_cmp(s_pnt, s)) == 0) {
          // Found
          break;
        }
      }
// # endif
    }
  }

#endif

  return r;
}