Ejemplo n.º 1
0
static int openssl_crl_extensions(lua_State* L)
{
  X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl");
  if (lua_isnone(L, 2))
  {
    STACK_OF(X509_EXTENSION) *exts = crl->crl->extensions;
    if (exts)
    {
      openssl_sk_x509_extension_totable(L, exts);
    }
    else
      lua_pushnil(L);
    return 1;
  }
  else
  {
    STACK_OF(X509_EXTENSION) *exts = openssl_sk_x509_extension_fromtable(L, 2);
    int i, n;
    n = sk_X509_EXTENSION_num(exts);
    for (i = 0; i < n; i++)
    {
      X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
      X509_CRL_add_ext(crl, X509_EXTENSION_dup(ext), i);
    };
    sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
    return openssl_pushresult(L, 1);
  }
}
Ejemplo n.º 2
0
int protocol_checkcert(void *peer, X509 * cert)
{
  struct in_network net;
  int i, j;
  const unsigned char *p;
  void *ext_str = NULL;
  const STACK_OF(X509_EXTENSION) * exts = cert->cert_info->extensions;
  X509_EXTENSION *ext;
  X509V3_EXT_METHOD *method;
  STACK_OF(GENERAL_SUBTREE) * trees;
  GENERAL_SUBTREE *tree;

  for (i = 0; i < sk_X509_EXTENSION_num(exts); i++)
    {
      ext = sk_X509_EXTENSION_value(exts, i);
      if ((method = X509V3_EXT_get(ext))
          && method->ext_nid == NID_name_constraints)
        {
          p = ext->value->data;
          if (method->it)
            ext_str = ASN1_item_d2i(NULL, &p, ext->value->length,
                                    ASN1_ITEM_ptr(method->it));
          else
            ext_str = method->d2i(NULL, &p, ext->value->length);

          trees = ((NAME_CONSTRAINTS *) ext_str)->permittedSubtrees;
          for (j = 0; j < sk_GENERAL_SUBTREE_num(trees); j++)
            {
              tree = sk_GENERAL_SUBTREE_value(trees, j);
              if (tree->base->type == GEN_IPADD)
                p = tree->base->d.ip->data;
              if (tree->base->d.ip->length == 8)
                {
                  net.addr.s_addr = *((uint32_t *) p);
                  net.netmask.s_addr = *((uint32_t *) & p[4]);
                  printf("%s/", inet_ntoa(net.addr));
                  printf("%s\n", inet_ntoa(net.netmask));
                }
//else if(len == 32) //IPv6
//  See openssl/crypto/x509v3/v3_ncons.c:static int print_nc_ipadd()
//else //DNS
//  GENERAL_NAME_print(bp, tree->base);
            }
        }
    }
  return 0;
}
Ejemplo n.º 3
0
static int openssl_xexts_totable(lua_State*L)
{
  STACK_OF(X509_EXTENSION) *exts = CHECK_OBJECT(1, STACK_OF(X509_EXTENSION), "openssl.stack_of_x509_extension");
  int utf8 = lua_isnoneornil(L, 2) ? 1 : lua_toboolean(L, 2);
  int i;
  int n = sk_X509_EXTENSION_num(exts);
  lua_newtable(L);

  for (i = 0; i < n; i++)
  {
    X509_EXTENSION* ext = sk_X509_EXTENSION_value(exts, i);

    openssl_xext_totable(L, ext);
    lua_rawseti(L, -2, i + 1);
  };
  return 1;
}
Ejemplo n.º 4
0
int X509_REQ_print_ex(BIO *bio, X509_REQ *x, unsigned long nmflags,
                      unsigned long cflag) {
  long l;
  EVP_PKEY *pkey;
  STACK_OF(X509_ATTRIBUTE) * sk;
  char mlch = ' ';

  int nmindent = 0;

  if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
    mlch = '\n';
    nmindent = 12;
  }

  if (nmflags == X509_FLAG_COMPAT) {
    nmindent = 16;
  }

  X509_REQ_INFO *ri = x->req_info;
  if (!(cflag & X509_FLAG_NO_HEADER)) {
    if (BIO_write(bio, "Certificate Request:\n", 21) <= 0 ||
        BIO_write(bio, "    Data:\n", 10) <= 0) {
      goto err;
    }
  }
  if (!(cflag & X509_FLAG_NO_VERSION)) {
    l = X509_REQ_get_version(x);
    if (BIO_printf(bio, "%8sVersion: %ld (0x%lx)\n", "", l + 1, l) <= 0) {
      goto err;
    }
  }
  if (!(cflag & X509_FLAG_NO_SUBJECT)) {
    if (BIO_printf(bio, "        Subject:%c", mlch) <= 0 ||
        X509_NAME_print_ex(bio, ri->subject, nmindent, nmflags) < 0 ||
        BIO_write(bio, "\n", 1) <= 0) {
      goto err;
    }
  }
  if (!(cflag & X509_FLAG_NO_PUBKEY)) {
    if (BIO_write(bio, "        Subject Public Key Info:\n", 33) <= 0 ||
        BIO_printf(bio, "%12sPublic Key Algorithm: ", "") <= 0 ||
        i2a_ASN1_OBJECT(bio, ri->pubkey->algor->algorithm) <= 0 ||
        BIO_puts(bio, "\n") <= 0) {
      goto err;
    }

    pkey = X509_REQ_get_pubkey(x);
    if (pkey == NULL) {
      BIO_printf(bio, "%12sUnable to load Public Key\n", "");
      ERR_print_errors(bio);
    } else {
      EVP_PKEY_print_public(bio, pkey, 16, NULL);
      EVP_PKEY_free(pkey);
    }
  }

  if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) {
    if (BIO_printf(bio, "%8sAttributes:\n", "") <= 0) {
      goto err;
    }

    sk = x->req_info->attributes;
    if (sk_X509_ATTRIBUTE_num(sk) == 0) {
      if (BIO_printf(bio, "%12sa0:00\n", "") <= 0) {
        goto err;
      }
    } else {
      size_t i;
      for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
        X509_ATTRIBUTE *a = sk_X509_ATTRIBUTE_value(sk, i);
        ASN1_OBJECT *aobj = X509_ATTRIBUTE_get0_object(a);

        if (X509_REQ_extension_nid(OBJ_obj2nid(aobj))) {
          continue;
        }

        if (BIO_printf(bio, "%12s", "") <= 0) {
          goto err;
        }

        const int num_attrs = X509_ATTRIBUTE_count(a);
        const int obj_str_len = i2a_ASN1_OBJECT(bio, aobj);
        if (obj_str_len <= 0) {
          if (BIO_puts(bio, "(Unable to print attribute ID.)\n") < 0) {
            goto err;
          } else {
            continue;
          }
        }

        int j;
        for (j = 0; j < num_attrs; j++) {
          const ASN1_TYPE *at = X509_ATTRIBUTE_get0_type(a, j);
          const int type = at->type;
          ASN1_BIT_STRING *bs = at->value.asn1_string;

          int k;
          for (k = 25 - obj_str_len; k > 0; k--) {
            if (BIO_write(bio, " ", 1) != 1) {
              goto err;
            }
          }

          if (BIO_puts(bio, ":") <= 0) {
            goto err;
          }

          if (type == V_ASN1_PRINTABLESTRING ||
              type == V_ASN1_UTF8STRING ||
              type == V_ASN1_IA5STRING ||
              type == V_ASN1_T61STRING) {
            if (BIO_write(bio, (char *)bs->data, bs->length) != bs->length) {
              goto err;
            }
            BIO_puts(bio, "\n");
          } else {
            BIO_puts(bio, "unable to print attribute\n");
          }
        }
      }
    }
  }

  if (!(cflag & X509_FLAG_NO_EXTENSIONS)) {
    STACK_OF(X509_EXTENSION) *exts = X509_REQ_get_extensions(x);
    if (exts) {
      BIO_printf(bio, "%8sRequested Extensions:\n", "");

      size_t i;
      for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
        X509_EXTENSION *ex = sk_X509_EXTENSION_value(exts, i);
        if (BIO_printf(bio, "%12s", "") <= 0) {
          goto err;
        }
        ASN1_OBJECT *obj = X509_EXTENSION_get_object(ex);
        i2a_ASN1_OBJECT(bio, obj);
        const int is_critical = X509_EXTENSION_get_critical(ex);
        if (BIO_printf(bio, ": %s\n", is_critical ? "critical" : "") <= 0) {
          goto err;
        }
        if (!X509V3_EXT_print(bio, ex, cflag, 16)) {
          BIO_printf(bio, "%16s", "");
          ASN1_STRING_print(bio, X509_EXTENSION_get_data(ex));
        }
        if (BIO_write(bio, "\n", 1) <= 0) {
          goto err;
        }
      }
      sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
    }
  }

  if (!(cflag & X509_FLAG_NO_SIGDUMP) &&
      !X509_signature_print(bio, x->sig_alg, x->signature)) {
    goto err;
  }

  return 1;

err:
  OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
  return 0;
}
Ejemplo n.º 5
0
int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, unsigned long cflag)
	{
	unsigned long l;
	int i;
	const char *neg;
	X509_REQ_INFO *ri;
	EVP_PKEY *pkey;
	STACK_OF(X509_ATTRIBUTE) *sk;
	STACK_OF(X509_EXTENSION) *exts;
	char mlch = ' ';
	int nmindent = 0;

	if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
		mlch = '\n';
		nmindent = 12;
	}

	if(nmflags == X509_FLAG_COMPAT)
		nmindent = 16;


	ri=x->req_info;
	if(!(cflag & X509_FLAG_NO_HEADER))
		{
		if (BIO_write(bp,"Certificate Request:\n",21) <= 0) goto err;
		if (BIO_write(bp,"    Data:\n",10) <= 0) goto err;
		}
	if(!(cflag & X509_FLAG_NO_VERSION))
		{
		neg=(ri->version->type == V_ASN1_NEG_INTEGER)?"-":"";
		l=0;
		for (i=0; i<ri->version->length; i++)
			{ l<<=8; l+=ri->version->data[i]; }
		if(BIO_printf(bp,"%8sVersion: %s%lu (%s0x%lx)\n","",neg,l,neg,
			      l) <= 0)
		    goto err;
		}
        if(!(cflag & X509_FLAG_NO_SUBJECT))
                {
                if (BIO_printf(bp,"        Subject:%c",mlch) <= 0) goto err;
                if (X509_NAME_print_ex(bp,ri->subject,nmindent, nmflags) < 0) goto err;
                if (BIO_write(bp,"\n",1) <= 0) goto err;
                }
	if(!(cflag & X509_FLAG_NO_PUBKEY))
		{
		if (BIO_write(bp,"        Subject Public Key Info:\n",33) <= 0)
			goto err;
		if (BIO_printf(bp,"%12sPublic Key Algorithm: ","") <= 0)
			goto err;
		if (i2a_ASN1_OBJECT(bp, ri->pubkey->algor->algorithm) <= 0)
			goto err;
		if (BIO_puts(bp, "\n") <= 0)
			goto err;

		pkey=X509_REQ_get_pubkey(x);
		if (pkey == NULL)
			{
			BIO_printf(bp,"%12sUnable to load Public Key\n","");
			ERR_print_errors(bp);
			}
		else
#ifndef OPENSSL_NO_RSA
		if (pkey->type == EVP_PKEY_RSA)
			{
			BIO_printf(bp,"%12sRSA Public Key: (%d bit)\n","",
			BN_num_bits(pkey->pkey.rsa->n));
			RSA_print(bp,pkey->pkey.rsa,16);
			}
		else
#endif
#ifndef OPENSSL_NO_DSA
		if (pkey->type == EVP_PKEY_DSA)
			{
			BIO_printf(bp,"%12sDSA Public Key:\n","");
			DSA_print(bp,pkey->pkey.dsa,16);
			}
		else
#endif
#ifndef OPENSSL_NO_EC
		if (pkey->type == EVP_PKEY_EC)
		{
			BIO_printf(bp, "%12sEC Public Key: \n","");
			EC_KEY_print(bp, pkey->pkey.ec, 16);
		}
	else
#endif
			BIO_printf(bp,"%12sUnknown Public Key:\n","");

		EVP_PKEY_free(pkey);
		}

	if(!(cflag & X509_FLAG_NO_ATTRIBUTES))
		{
		/* may not be */
		if(BIO_printf(bp,"%8sAttributes:\n","") <= 0)
		    goto err;

		sk=x->req_info->attributes;
		if (sk_X509_ATTRIBUTE_num(sk) == 0)
			{
			if(BIO_printf(bp,"%12sa0:00\n","") <= 0)
			    goto err;
			}
		else
			{
			for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
				{
				ASN1_TYPE *at;
				X509_ATTRIBUTE *a;
				ASN1_BIT_STRING *bs=NULL;
				ASN1_TYPE *t;
				int j,type=0,count=1,ii=0;

				a=sk_X509_ATTRIBUTE_value(sk,i);
				if(X509_REQ_extension_nid(OBJ_obj2nid(a->object)))
									continue;
				if(BIO_printf(bp,"%12s","") <= 0)
				    goto err;
				if ((j=i2a_ASN1_OBJECT(bp,a->object)) > 0)
				{
				if (a->single)
					{
					t=a->value.single;
					type=t->type;
					bs=t->value.bit_string;
					}
				else
					{
					ii=0;
					count=sk_ASN1_TYPE_num(a->value.set);
get_next:
					at=sk_ASN1_TYPE_value(a->value.set,ii);
					type=at->type;
					bs=at->value.asn1_string;
					}
				}
				for (j=25-j; j>0; j--)
					if (BIO_write(bp," ",1) != 1) goto err;
				if (BIO_puts(bp,":") <= 0) goto err;
				if (	(type == V_ASN1_PRINTABLESTRING) ||
					(type == V_ASN1_T61STRING) ||
					(type == V_ASN1_IA5STRING))
					{
					if (BIO_write(bp,(char *)bs->data,bs->length)
						!= bs->length)
						goto err;
					BIO_puts(bp,"\n");
					}
				else
					{
					BIO_puts(bp,"unable to print attribute\n");
					}
				if (++ii < count) goto get_next;
				}
			}
		}
	if(!(cflag & X509_FLAG_NO_EXTENSIONS))
		{
		exts = X509_REQ_get_extensions(x);
		if(exts)
			{
			BIO_printf(bp,"%8sRequested Extensions:\n","");
			for (i=0; i<sk_X509_EXTENSION_num(exts); i++)
				{
				ASN1_OBJECT *obj;
				X509_EXTENSION *ex;
				int j;
				ex=sk_X509_EXTENSION_value(exts, i);
				if (BIO_printf(bp,"%12s","") <= 0) goto err;
				obj=X509_EXTENSION_get_object(ex);
				i2a_ASN1_OBJECT(bp,obj);
				j=X509_EXTENSION_get_critical(ex);
				if (BIO_printf(bp,": %s\n",j?"critical":"") <= 0)
					goto err;
				if(!X509V3_EXT_print(bp, ex, cflag, 16))
					{
					BIO_printf(bp, "%16s", "");
					M_ASN1_OCTET_STRING_print(bp,ex->value);
					}
				if (BIO_write(bp,"\n",1) <= 0) goto err;
				}
			sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
			}
		}

	if(!(cflag & X509_FLAG_NO_SIGDUMP))
		{
		if(!X509_signature_print(bp, x->sig_alg, x->signature)) goto err;
		}

	return(1);
err:
	X509err(X509_F_X509_REQ_PRINT_EX,ERR_R_BUF_LIB);
	return(0);
	}
Ejemplo n.º 6
0
/*
 * The X509_CRL structure needs a bit of customisation. Cache some extensions
 * and hash of the whole CRL.
 */
static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
                  void *exarg)
{
    X509_CRL *crl = (X509_CRL *)*pval;
    STACK_OF(X509_EXTENSION) *exts;
    X509_EXTENSION *ext;
    int idx;

    switch (operation) {
    case ASN1_OP_NEW_POST:
        crl->idp = NULL;
        crl->akid = NULL;
        crl->flags = 0;
        crl->idp_flags = 0;
        crl->idp_reasons = CRLDP_ALL_REASONS;
        crl->meth = default_crl_method;
        crl->meth_data = NULL;
        crl->issuers = NULL;
        crl->crl_number = NULL;
        crl->base_crl_number = NULL;
        break;

    case ASN1_OP_D2I_POST:
        X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
        crl->idp = X509_CRL_get_ext_d2i(crl,
                                        NID_issuing_distribution_point, NULL,
                                        NULL);
        if (crl->idp)
            setup_idp(crl, crl->idp);

        crl->akid = X509_CRL_get_ext_d2i(crl,
                                         NID_authority_key_identifier, NULL,
                                         NULL);

        crl->crl_number = X509_CRL_get_ext_d2i(crl,
                                               NID_crl_number, NULL, NULL);

        crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
                                                    NID_delta_crl, NULL,
                                                    NULL);
        /* Delta CRLs must have CRL number */
        if (crl->base_crl_number && !crl->crl_number)
            crl->flags |= EXFLAG_INVALID;

        /*
         * See if we have any unhandled critical CRL extensions and indicate
         * this in a flag. We only currently handle IDP so anything else
         * critical sets the flag. This code accesses the X509_CRL structure
         * directly: applications shouldn't do this.
         */

        exts = crl->crl.extensions;

        for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) {
            int nid;
            ext = sk_X509_EXTENSION_value(exts, idx);
            nid = OBJ_obj2nid(X509_EXTENSION_get_object(ext));
            if (nid == NID_freshest_crl)
                crl->flags |= EXFLAG_FRESHEST;
            if (X509_EXTENSION_get_critical(ext)) {
                /* We handle IDP and deltas */
                if ((nid == NID_issuing_distribution_point)
                    || (nid == NID_authority_key_identifier)
                    || (nid == NID_delta_crl))
                    break;;
                crl->flags |= EXFLAG_CRITICAL;
                break;
            }
        }

        if (!crl_set_issuers(crl))
            return 0;

        if (crl->meth->crl_init) {
            if (crl->meth->crl_init(crl) == 0)
                return 0;
        }
        break;

    case ASN1_OP_FREE_POST:
        if (crl->meth->crl_free) {
            if (!crl->meth->crl_free(crl))
                return 0;
        }
        AUTHORITY_KEYID_free(crl->akid);
        ISSUING_DIST_POINT_free(crl->idp);
        ASN1_INTEGER_free(crl->crl_number);
        ASN1_INTEGER_free(crl->base_crl_number);
        sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
        break;
    }
    return 1;
}
Ejemplo n.º 7
0
static int crl_set_issuers(X509_CRL *crl)
{

    int i, j;
    GENERAL_NAMES *gens, *gtmp;
    STACK_OF(X509_REVOKED) *revoked;

    revoked = X509_CRL_get_REVOKED(crl);

    gens = NULL;
    for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) {
        X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
        STACK_OF(X509_EXTENSION) *exts;
        ASN1_ENUMERATED *reason;
        X509_EXTENSION *ext;
        gtmp = X509_REVOKED_get_ext_d2i(rev,
                                        NID_certificate_issuer, &j, NULL);
        if (!gtmp && (j != -1)) {
            crl->flags |= EXFLAG_INVALID;
            return 1;
        }

        if (gtmp) {
            gens = gtmp;
            if (!crl->issuers) {
                crl->issuers = sk_GENERAL_NAMES_new_null();
                if (!crl->issuers)
                    return 0;
            }
            if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
                return 0;
        }
        rev->issuer = gens;

        reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason, &j, NULL);
        if (!reason && (j != -1)) {
            crl->flags |= EXFLAG_INVALID;
            return 1;
        }

        if (reason) {
            rev->reason = ASN1_ENUMERATED_get(reason);
            ASN1_ENUMERATED_free(reason);
        } else
            rev->reason = CRL_REASON_NONE;

        /* Check for critical CRL entry extensions */

        exts = rev->extensions;

        for (j = 0; j < sk_X509_EXTENSION_num(exts); j++) {
            ext = sk_X509_EXTENSION_value(exts, j);
            if (X509_EXTENSION_get_critical(ext)) {
                if (OBJ_obj2nid(X509_EXTENSION_get_object(ext)) == NID_certificate_issuer)
                    continue;
                crl->flags |= EXFLAG_CRITICAL;
                break;
            }
        }

    }

    return 1;

}
Ejemplo n.º 8
0
int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags,
                      unsigned long cflag)
{
    long l;
    int i;
    X509_REQ_INFO *ri;
    EVP_PKEY *pkey;
    STACK_OF(X509_ATTRIBUTE) *sk;
    STACK_OF(X509_EXTENSION) *exts;
    char mlch = ' ';
    int nmindent = 0;

    if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
        mlch = '\n';
        nmindent = 12;
    }

    if (nmflags == X509_FLAG_COMPAT)
        nmindent = 16;

    ri = x->req_info;
    if (!(cflag & X509_FLAG_NO_HEADER)) {
        if (BIO_write(bp, "Certificate Request:\n", 21) <= 0)
            goto err;
        if (BIO_write(bp, "    Data:\n", 10) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_VERSION)) {
        l = X509_REQ_get_version(x);
        if (BIO_printf(bp, "%8sVersion: %ld (0x%lx)\n", "", l + 1, l) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_SUBJECT)) {
        if (BIO_printf(bp, "        Subject:%c", mlch) <= 0)
            goto err;
        if (X509_NAME_print_ex(bp, ri->subject, nmindent, nmflags) < 0)
            goto err;
        if (BIO_write(bp, "\n", 1) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_PUBKEY)) {
        if (BIO_write(bp, "        Subject Public Key Info:\n", 33) <= 0)
            goto err;
        if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
            goto err;
        if (i2a_ASN1_OBJECT(bp, ri->pubkey->algor->algorithm) <= 0)
            goto err;
        if (BIO_puts(bp, "\n") <= 0)
            goto err;

        pkey = X509_REQ_get_pubkey(x);
        if (pkey == NULL) {
            BIO_printf(bp, "%12sUnable to load Public Key\n", "");
            ERR_print_errors(bp);
        } else {
            EVP_PKEY_print_public(bp, pkey, 16, NULL);
            EVP_PKEY_free(pkey);
        }
    }

    if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) {
        /* may not be */
        if (BIO_printf(bp, "%8sAttributes:\n", "") <= 0)
            goto err;

        sk = x->req_info->attributes;
        if (sk_X509_ATTRIBUTE_num(sk) == 0) {
            if (BIO_printf(bp, "%12sa0:00\n", "") <= 0)
                goto err;
        } else {
            for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
                ASN1_TYPE *at;
                X509_ATTRIBUTE *a;
                ASN1_BIT_STRING *bs = NULL;
                ASN1_OBJECT *aobj;
                int j, type = 0, count = 1, ii = 0;

                a = sk_X509_ATTRIBUTE_value(sk, i);
                aobj = X509_ATTRIBUTE_get0_object(a);
                if (X509_REQ_extension_nid(OBJ_obj2nid(aobj)))
                    continue;
                if (BIO_printf(bp, "%12s", "") <= 0)
                    goto err;
                if ((j = i2a_ASN1_OBJECT(bp, aobj)) > 0) {
                    ii = 0;
                    count = X509_ATTRIBUTE_count(a);
 get_next:
                    at = X509_ATTRIBUTE_get0_type(a, ii);
                    type = at->type;
                    bs = at->value.asn1_string;
                }
                for (j = 25 - j; j > 0; j--)
                    if (BIO_write(bp, " ", 1) != 1)
                        goto err;
                if (BIO_puts(bp, ":") <= 0)
                    goto err;
                if ((type == V_ASN1_PRINTABLESTRING) ||
                    (type == V_ASN1_T61STRING) ||
                    (type == V_ASN1_IA5STRING)) {
                    if (BIO_write(bp, (char *)bs->data, bs->length)
                        != bs->length)
                        goto err;
                    BIO_puts(bp, "\n");
                } else {
                    BIO_puts(bp, "unable to print attribute\n");
                }
                if (++ii < count)
                    goto get_next;
            }
        }
    }
    if (!(cflag & X509_FLAG_NO_EXTENSIONS)) {
        exts = X509_REQ_get_extensions(x);
        if (exts) {
            BIO_printf(bp, "%8sRequested Extensions:\n", "");
            for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
                ASN1_OBJECT *obj;
                X509_EXTENSION *ex;
                int j;
                ex = sk_X509_EXTENSION_value(exts, i);
                if (BIO_printf(bp, "%12s", "") <= 0)
                    goto err;
                obj = X509_EXTENSION_get_object(ex);
                i2a_ASN1_OBJECT(bp, obj);
                j = X509_EXTENSION_get_critical(ex);
                if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0)
                    goto err;
                if (!X509V3_EXT_print(bp, ex, cflag, 16)) {
                    BIO_printf(bp, "%16s", "");
                    ASN1_STRING_print(bp, X509_EXTENSION_get_data(ex));
                }
                if (BIO_write(bp, "\n", 1) <= 0)
                    goto err;
            }
            sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
        }
    }

    if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
        if (!X509_signature_print(bp, x->sig_alg, x->signature))
            goto err;
    }

    return (1);
 err:
    X509err(X509_F_X509_REQ_PRINT_EX, ERR_R_BUF_LIB);
    return (0);
}
Ejemplo n.º 9
0
//============================================================
// Initializes NotaryInfo object with data from OCSP object
// pSigDoc - digidoc main object pointer
// pNotary - NotaryInfo object to be initialized
// resp - OCSP response object
// notCert - Notary cert object
// return error code
//============================================================
int initializeNotaryInfoWithOCSP(SignedDoc *pSigDoc, NotaryInfo *pNotary, 
				OCSP_RESPONSE *resp, X509 *notCert, int initDigest)
{
  int n, err = ERR_OK;
  char buf[500];
  OCSP_RESPBYTES *rb = NULL;
  OCSP_BASICRESP *br = NULL;
  OCSP_RESPDATA  *rd = NULL;
  OCSP_RESPID *rid = NULL;
  // OCSP_CERTSTATUS *cst = NULL;
  OCSP_SINGLERESP *single = NULL;
  OCSP_CERTID *cid = NULL;
  X509_EXTENSION *nonce;
	//AM 26.09.08
	DigiDocMemBuf mbuf1;
	mbuf1.pMem = 0;
	mbuf1.nLen = 0;
	
  RETURN_IF_NULL_PARAM(pNotary);
  RETURN_IF_NULL_PARAM(resp);
  // check the OCSP Response validity
  switch(OCSP_response_status(resp)) {
  case OCSP_RESPONSE_STATUS_SUCCESSFUL: // OK
    break;
  case OCSP_RESPONSE_STATUS_MALFORMEDREQUEST:
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_MALFORMED);
  case OCSP_RESPONSE_STATUS_INTERNALERROR:
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_INTERNALERR);
  case OCSP_RESPONSE_STATUS_TRYLATER:
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_TRYLATER);
  case OCSP_RESPONSE_STATUS_SIGREQUIRED:
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_SIGREQUIRED);
  case OCSP_RESPONSE_STATUS_UNAUTHORIZED:
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_UNAUTHORIZED);
  default:
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_UNSUCCESSFUL);
  }
  RETURN_IF_NULL_PARAM(resp->responseBytes);;
  rb = resp->responseBytes;
  if(OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) 
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_UNKNOWN_TYPE);
  if((br = OCSP_response_get1_basic(resp)) == NULL) 
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_BASIC_RESP);
  rd = br->tbsResponseData;
  if(ASN1_INTEGER_get(rd->version) != 0) 
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_WRONG_VERSION);
  n = sk_OCSP_SINGLERESP_num(rd->responses);
  if(n != 1) 
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_ONE_RESPONSE);
  single = sk_OCSP_SINGLERESP_value(rd->responses, 0);
  RETURN_IF_NULL(single);
  cid = single->certId;
  RETURN_IF_NULL(cid);
  ddocDebug(4, "initializeNotaryInfoWithOCSP", "CertStatus-type: %d", single->certStatus->type);
  //printf("TYPE: %d\n", single->certStatus->type);
  if(single->certStatus->type != 0) {
    ddocDebug(4, "initializeNotaryInfoWithOCSP", "errcode: %d", handleOCSPCertStatus(single->certStatus->type));
    SET_LAST_ERROR_RETURN_CODE(handleOCSPCertStatus(single->certStatus->type));
  }
  //Removed 31.10.2003
  //if(single->singleExtensions) 
  //	SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_SINGLE_EXT);
  if(!rd->responseExtensions ||
     (sk_X509_EXTENSION_num(rd->responseExtensions) != 1) ||
     ((nonce = sk_X509_EXTENSION_value(rd->responseExtensions, 0)) == NULL)) 
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_NONCE);
  i2t_ASN1_OBJECT(buf,sizeof(buf),nonce->object);
  if(strcmp(buf, OCSP_NONCE_NAME)) 
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_NONCE);
  rid =  rd->responderId;
  if(rid->type == V_OCSP_RESPID_NAME) {
    pNotary->nRespIdType = RESPID_NAME_TYPE;
  } else if(rid->type == V_OCSP_RESPID_KEY) {
    pNotary->nRespIdType = RESPID_KEY_TYPE;
  } else {
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_WRONG_RESPID);
  }
  // producedAt
  err = asn1time2str(pSigDoc, rd->producedAt, buf, sizeof(buf));
  setString(&(pNotary->timeProduced), buf, -1);
  n = sizeof(buf);
  if(rid->type == V_OCSP_RESPID_NAME) {
    //X509_NAME_oneline(rid->value.byName,buf,n);
		//AM 26.09.08
		err = ddocCertGetDNFromName(rid->value.byName, &mbuf1);
		RETURN_IF_NOT(err == ERR_OK, err);
		err = ddocNotInfo_SetResponderId(pNotary, (char*)mbuf1.pMem, -1);
		ddocMemBuf_free(&mbuf1);
  }
  if(rid->type == V_OCSP_RESPID_KEY) {
    err = ddocNotInfo_SetResponderId(pNotary, (const char*)rid->value.byKey->data, rid->value.byKey->length);
  }
  // digest type
  i2t_ASN1_OBJECT(buf,sizeof(buf),cid->hashAlgorithm->algorithm);
  setString(&(pNotary->szDigestType), buf, -1);
  // signature algorithm
  i2t_ASN1_OBJECT(buf,sizeof(buf),br->signatureAlgorithm->algorithm);
  setString(&(pNotary->szSigType), buf, -1);
  // notary cert
  if(notCert && !err)
    err = addNotaryInfoCert(pSigDoc, pNotary, notCert);
  // save the response in memory
  err = ddocNotInfo_SetOCSPResponse_Value(pNotary, resp);
  // get the digest from original OCSP data
  if(initDigest && notCert) {
    err = calcNotaryDigest(pSigDoc, pNotary);
  }
  if(br != NULL)
    OCSP_BASICRESP_free(br);
  if (err != ERR_OK) SET_LAST_ERROR(err);
  return err;
}
Ejemplo n.º 10
0
void anubis_dump_server_certificate(SSL *ssl) {
    X509 *x509Cert = SSL_get_peer_certificate(ssl);
    char buffer[1024];
    BIO *bio = NULL;
    char *buf = NULL;
    
    if(!x509Cert) {
        anubis_ssl_perror("SSL_get_peer_certificate()");
        return;
    }
    
    bio = BIO_new(BIO_s_mem());
    if(!bio) {
        anubis_ssl_perror("BIO_new()");
        X509_free(x509Cert);
        return;
    }//end if
    
    BIO_reset(bio);
    if(!PEM_write_bio_X509(bio, x509Cert)) {
        anubis_ssl_perror("PEM_write_bio_X509()");
        BIO_free(bio);
        X509_free(x509Cert);
        return;
    }
    BIO_get_mem_data(bio, &buf);
    anubis_out("Server certificate:\n%s", buf);
    // Cert Version
    long version = 0;
    if (!(X509_FLAG_COMPAT & X509_FLAG_NO_VERSION)) {
        version = X509_get_version(x509Cert);
        fprintf(out_stream, "Version: %ld\n", version);
    }//end if
    
    // Cert Serial No. - Code adapted from OpenSSL's crypto/asn1/t_x509.c
    if (!(X509_FLAG_COMPAT & X509_FLAG_NO_SERIAL)) {
        ASN1_INTEGER *bs;
        long l;
        int i;
        const char *neg;
        bs = X509_get_serialNumber(x509Cert);
        
        if (bs->length <= 4) {
            l = ASN1_INTEGER_get(bs);
            if (l < 0) {
                l= -l;
                neg = "-";
            }
            else
                neg = "";
            
            fprintf(out_stream, "Serial Number: %lu (%#lx)\n", l, l);
        }
        else {
            neg = (bs->type == V_ASN1_NEG_INTEGER)?" (Negative)":"";
            fprintf(out_stream, "Serial Number: %s", neg);
            for (i = 0; i < bs->length; i++) {
                fprintf(out_stream, "%02x%c", bs->data[i], (i+1 == bs->length)?'\n':':');
            }
        }
    }
    
    // Signature Algo...
    if (!(X509_FLAG_COMPAT & X509_FLAG_NO_SIGNAME)) {
        i2a_ASN1_OBJECT(bio, x509Cert->cert_info->signature->algorithm);
        BIO_get_mem_data(bio, &buf);
        fprintf(out_stream, "Signature Algorithm:\n%s\n", buf);
    }
    
    // SSL Certificate Issuer...
    if (!(X509_FLAG_COMPAT & X509_FLAG_NO_ISSUER)) {
        X509_NAME_oneline(X509_get_issuer_name(x509Cert), buffer, sizeof(buffer) - 1);
        fprintf(out_stream, "Issuer: %s\n", buffer);
    }
    
    // Validity...
    if (!(X509_FLAG_COMPAT & X509_FLAG_NO_VALIDITY)) {
        BIO_reset(bio);
        ASN1_TIME_print(bio, X509_get_notBefore(x509Cert));
        BIO_get_mem_data(bio, &buf);
        fprintf(out_stream, "Not Valid Before: %s\n", buf);
        
        BIO_reset(bio);
        ASN1_TIME_print(bio, X509_get_notAfter(x509Cert));
        BIO_get_mem_data(bio, &buf);
        fprintf(out_stream, "Not Valid After: %s\n", buf);
    }
    
    // SSL Certificate Subject...
    if (!(X509_FLAG_COMPAT & X509_FLAG_NO_SUBJECT)) {
        X509_NAME_oneline(X509_get_subject_name(x509Cert), buffer, sizeof(buffer) - 1);
        fprintf(out_stream, "Subject: %s\n", buffer);
    }
    
    // Public Key Algo...
    if (!(X509_FLAG_COMPAT & X509_FLAG_NO_PUBKEY)) {
        BIO_reset(bio);
        i2a_ASN1_OBJECT(bio, x509Cert->cert_info->key->algor->algorithm);
        BIO_get_mem_data(bio, &buf);
        fprintf(out_stream, "Public Key Algorithm: %s\n", buf);
        
        // Public Key...
        EVP_PKEY *publicKey = NULL;
        publicKey = X509_get_pubkey(x509Cert);
        if (publicKey == NULL) {
            anubis_err("Public Key Could not load\n");
        }
        else {
            BIO_reset(bio);
            char *publicKeyType = NULL;
            int publicKeyLength = -1;
            switch (publicKey->type) {
                case EVP_PKEY_RSA:
                    
                    publicKeyType = "RSA";
                    
                    if (publicKey->pkey.rsa) {
                        publicKeyLength = BN_num_bits(publicKey->pkey.rsa->n);
                        RSA_print(bio, publicKey->pkey.rsa, 0);
                        BIO_get_mem_data(bio, &buf);
                    }
                    break;
                case EVP_PKEY_DSA:
                    
                    publicKeyType = "DSA";
                    
                    if (publicKey->pkey.dsa) {
                        DSA_print(bio, publicKey->pkey.dsa, 0);
                        BIO_get_mem_data(bio, &buf);
                    }
                    break;
                case EVP_PKEY_EC:
                    publicKeyType = "EC";
                    
                    if (publicKey->pkey.ec)  {
                        EC_KEY_print(bio, publicKey->pkey.ec, 0);
                        BIO_get_mem_data(bio, &buf);
                    }
                    break;
                default:
                    publicKeyType = "Unknown";
                    break;
            }
            
            EVP_PKEY_free(publicKey);
            fprintf(out_stream, "%d Public Key: ", publicKeyLength);
            if(!strcasecmp(publicKeyType, "RSA")) {
                fprintf(out_stream, "(%d bits)", publicKeyLength);
            }
            fprintf(out_stream, "\n");
            fprintf(out_stream, "%s\n", buf);
        }
    }
    
    // X509 v3...
    if (!(X509_FLAG_COMPAT & X509_FLAG_NO_EXTENSIONS) && sk_X509_EXTENSION_num(x509Cert->cert_info->extensions) > 0) {
        X509_EXTENSION *extension = NULL;
        ASN1_OBJECT *asn1Object = NULL;
        int tempInt2 = 0;
        BIO_reset(bio);
        for (int tempInt = 0; tempInt < sk_X509_EXTENSION_num(x509Cert->cert_info->extensions); tempInt++) {
            // Get Extension...
            extension = sk_X509_EXTENSION_value(x509Cert->cert_info->extensions, tempInt);
            
            asn1Object = X509_EXTENSION_get_object(extension);
            i2a_ASN1_OBJECT(bio, asn1Object);
            tempInt2 = X509_EXTENSION_get_critical(extension);
            BIO_printf(bio, ": %s\n", tempInt2 ? "critical" : "");
            
            // Print Extension value...
            if (!X509V3_EXT_print(bio, extension, X509_FLAG_COMPAT, 8)) {
                M_ASN1_OCTET_STRING_print(bio, extension->value);
            }
            BIO_printf(bio, "\n");
        }//end for
        
        BIO_get_mem_data(bio, &buf);
        fprintf(out_stream, "x509v3 Extensions: %s\n", buf);
    }//end if x509v3
    
    /*
    long verifyError = 0;
    // Verify Certificate...
    verifyError = SSL_get_verify_result(ssl);
    const char *verifyCertificate = "";
    if (verifyError == X509_V_OK)
        verifyCertificate = "Certificate passed verification";
    else
        verifyCertificate = X509_verify_cert_error_string(verifyError);
    fprintf(out_stream, "Validation: %s\n", verifyCertificate);
    */
    
    BIO_free(bio);
    X509_free(x509Cert);
    fflush(out_stream);
}//end anubis_dump_server_certificate
Ejemplo n.º 11
0
int protocol_checknameconstraints(const struct peer_s *peer)
{
  struct in_network ncnet, *shnet;
  int i, j, r, ret = 0, valid = 0;
  const unsigned char *p;
  void *ext_str = NULL;
  X509 *cert;
  STACK_OF(X509_EXTENSION) * exts;
  X509_EXTENSION *ext;
  const X509V3_EXT_METHOD *method;
  STACK_OF(GENERAL_SUBTREE) * trees;
  GENERAL_SUBTREE *tree;

  pthread_mutex_lock(&peer->udpsrvsession->dtls_mutex);
  cert = SSL_get_peer_certificate(peer->udpsrvsession->dtls);
  exts = cert->cert_info->extensions;
  for (r = 0; r < peer->shared_networks_len; r++)
    {
      shnet = &peer->shared_networks[r];
      for (i = 0; i < sk_X509_EXTENSION_num(exts); i++)
        {
          ext = sk_X509_EXTENSION_value(exts, i);
          if ((method = X509V3_EXT_get(ext))
              && method->ext_nid == NID_name_constraints)
            {
              p = ext->value->data;
              if (method->it)
                ext_str = ASN1_item_d2i(NULL, &p, ext->value->length,
                                        ASN1_ITEM_ptr(method->it));
              else
                ext_str = method->d2i(NULL, &p, ext->value->length);

              trees = ((NAME_CONSTRAINTS *) ext_str)->permittedSubtrees;
              for (j = 0; j < sk_GENERAL_SUBTREE_num(trees); j++)
                {
                  tree = sk_GENERAL_SUBTREE_value(trees, j);
                  if (tree->base->type == GEN_IPADD)
                    {
                      if (tree->base->d.ip->length == 8)
                        {
                          ncnet.addr.s_addr =
                            *((uint32_t *) tree->base->d.ip->data);
                          ncnet.netmask.s_addr =
                            *((uint32_t *) & tree->base->d.ip->data[4]);
                          if (shnet->netmask.s_addr >= ncnet.netmask.s_addr
                              && (ncnet.addr.s_addr & ncnet.netmask.s_addr)
                              == (shnet->addr.s_addr &
                                  shnet->netmask.s_addr))
                            valid++;
                        }
//else if(tree->base->d.ip->length == 32) //IPv6
//  See openssl/crypto/x509v3/v3_ncons.c:static int print_nc_ipadd()
//} else { //DNS
//  GENERAL_NAME_print(bp, tree->base);
                    }
                }
            }
        }
      if (valid == 0){
        ret = -1;
        break;
      }
      ret += valid;
      valid = 0;
    }
  pthread_mutex_unlock(&peer->udpsrvsession->dtls_mutex);
  return ret;
}
Ejemplo n.º 12
0
bool InteropResolver::checkMatch(DSIGKeyInfoList * lst, X509 * x) {

	// Check if the parameters in x match the required certificate


	int sz = (int) lst->getSize();
	DSIGKeyInfo* k;
	
	for (int i = 0; i < sz; ++i) {

		k = lst->item(i);

		if (k->getKeyInfoType() == DSIGKeyInfo::KEYINFO_X509) {

			DSIGKeyInfoX509 * kx = static_cast<DSIGKeyInfoX509 *>(k);
			
			const XMLCh * serial = kx->getX509IssuerSerialNumber();

			if (serial != NULL) {

				char * cserial = XMLString::transcode(serial);
				char * xserial;

				BIGNUM * bnserial = ASN1_INTEGER_to_BN(x->cert_info->serialNumber, NULL);
				xserial = BN_bn2dec(bnserial);
				BN_free(bnserial);

				if (strcmp(xserial, cserial) == 0) {
					
					OPENSSL_free(xserial);
					XSEC_RELEASE_XMLCH(cserial);
					return true;

				}
				//delete[] xserial;
				XSEC_RELEASE_XMLCH(cserial);
				OPENSSL_free(xserial);

			}

			/* 
			 * Either it's not a serial number, or we didn't pass, so lets
			 * look at the next option.
			 */
			
			const XMLCh * ski = kx->getX509SKI();
			
			if (ski != NULL) {

				char * cski = XMLString::transcode(ski);
				int clen = (int) strlen(cski);
				unsigned char * xski = new unsigned char[clen];
				ArrayJanitor <unsigned char> j_xski(xski);

				// Decode

				OpenSSLCryptoBase64 b64;
				b64.decodeInit();
				int xlen = b64.decode((unsigned char *) cski, clen, xski, clen);
				xlen += b64.decodeFinish(&xski[xlen], clen - xlen);
                XSEC_RELEASE_XMLCH(cski);

				if (xlen != 0) {

					// Have a buffer with a number in it
					STACK_OF(X509_EXTENSION) *exts;
					exts = x->cert_info->extensions;

					if (exts != NULL) {

						// Find the Subject Key Identifier OID
						X509_EXTENSION * ext;
						ASN1_OBJECT * objski = OBJ_nid2obj(NID_subject_key_identifier);
						int extn = X509v3_get_ext_by_OBJ(exts, objski, -1);
						if (extn != -1) {
							// Dummy up an OCTET_STRING from the xski
							unsigned char * octxski = new unsigned char[xlen + 2];
							ArrayJanitor<unsigned char> j_octxski(octxski);

							octxski[0] = 4;
							octxski[1] = xlen;
							memcpy(&octxski[2], xski, xlen);
							
							ext = sk_X509_EXTENSION_value(exts,extn);
							ASN1_OCTET_STRING *skid = ext->value;
							ASN1_OCTET_STRING * xskid = M_ASN1_OCTET_STRING_new();
							ASN1_STRING_set(xskid, octxski, xlen+2);
							
							if (ASN1_OCTET_STRING_cmp(xskid, skid) == 0) {
								ASN1_OCTET_STRING_free(xskid);
								return true;
							}
						}

					}

				}

			}

			/* Not a subject key identifier */
			const XMLCh *sn = kx->getX509SubjectName();

			if (sn != NULL) {

				char * csn = XMLString::transcode(sn);

				X509_NAME * x509name = X509_get_subject_name(x);
				X509_NAME * snname = X509_NAME_create_from_txt(csn);
				XSEC_RELEASE_XMLCH(csn);

				if (snname != NULL) {

					if (!X509_NAME_cmp(x509name, snname)) {
						X509_NAME_free(snname);
						return true;
					}
				
					X509_NAME_free(snname);
				}
			}
		}
	}

	return false;

}
Ejemplo n.º 13
0
/** Extract attributes from an X509 certificate
 *
 * @param cursor	to copy attributes to.
 * @param ctx		to allocate attributes in.
 * @param session	current TLS session.
 * @param cert		to validate.
 * @param depth		the certificate is in the certificate chain (0 == leaf).
 * @return
 *	- 0 on success.
 *	- < 0 on failure.
 */
int tls_session_pairs_from_x509_cert(fr_cursor_t *cursor, TALLOC_CTX *ctx,
				     tls_session_t *session, X509 *cert, int depth)
{
	char		buffer[1024];
	char		attribute[256];
	char		**identity;
	int		attr_index, loc;

#if OPENSSL_VERSION_NUMBER >= 0x10100000L
	STACK_OF(X509_EXTENSION) const *ext_list = NULL;
#else
	STACK_OF(X509_EXTENSION) *ext_list = NULL;
#endif

	ASN1_INTEGER	*sn = NULL;
	ASN1_TIME	*asn_time = NULL;

	VALUE_PAIR	*vp = NULL;

	REQUEST		*request;

#define CERT_ATTR_ADD(_attr, _attr_index, _value) tls_session_cert_attr_add(ctx, request, cursor, _attr, _attr_index, _value)

	attr_index = depth;
	if (attr_index > 1) attr_index = 1;

	request = (REQUEST *)SSL_get_ex_data(session->ssl, FR_TLS_EX_INDEX_REQUEST);
	rad_assert(request != NULL);

	identity = (char **)SSL_get_ex_data(session->ssl, FR_TLS_EX_INDEX_IDENTITY);

	if (RDEBUG_ENABLED3) {
		buffer[0] = '\0';
		X509_NAME_oneline(X509_get_subject_name(cert), buffer, sizeof(buffer));
		buffer[sizeof(buffer) - 1] = '\0';
		RDEBUG3("Creating attributes for \"%s\":", buffer[0] ? buffer : "Cert missing subject OID");
	}

	/*
	 *	Get the Serial Number
	 */
	sn = X509_get_serialNumber(cert);
	if (sn && ((size_t) sn->length < (sizeof(buffer) / 2))) {
		char *p = buffer;
		int i;

		for (i = 0; i < sn->length; i++) {
			sprintf(p, "%02x", (unsigned int)sn->data[i]);
			p += 2;
		}

		CERT_ATTR_ADD(IDX_SERIAL, attr_index, buffer);
	}

	/*
	 *	Get the Expiration Date
	 */
	buffer[0] = '\0';
	asn_time = X509_get_notAfter(cert);
	if (identity && asn_time && (asn_time->length < (int)sizeof(buffer))) {
		time_t expires;

		/*
		 *	Add expiration as a time since the epoch
		 */
		if (tls_utils_asn1time_to_epoch(&expires, asn_time) < 0) {
			RPWDEBUG("Failed parsing certificate expiry time");
		} else {
			vp = CERT_ATTR_ADD(IDX_EXPIRATION, attr_index, NULL);
			vp->vp_date = expires;
		}
	}

	/*
	 *	Get the Subject & Issuer
	 */
	buffer[0] = '\0';
	X509_NAME_oneline(X509_get_subject_name(cert), buffer, sizeof(buffer));
	buffer[sizeof(buffer) - 1] = '\0';
	if (identity && buffer[0]) {
		CERT_ATTR_ADD(IDX_SUBJECT, attr_index, buffer);

		/*
		 *	Get the Common Name, if there is a subject.
		 */
		X509_NAME_get_text_by_NID(X509_get_subject_name(cert),
					  NID_commonName, buffer, sizeof(buffer));
		buffer[sizeof(buffer) - 1] = '\0';

		if (buffer[0]) {
			CERT_ATTR_ADD(IDX_COMMON_NAME, attr_index, buffer);
		}
	}

	X509_NAME_oneline(X509_get_issuer_name(cert), buffer, sizeof(buffer));
	buffer[sizeof(buffer) - 1] = '\0';
	if (identity && buffer[0]) {
		CERT_ATTR_ADD(IDX_ISSUER, attr_index, buffer);
	}

	/*
	 *	Get the RFC822 Subject Alternative Name
	 */
	loc = X509_get_ext_by_NID(cert, NID_subject_alt_name, 0);
	if (loc >= 0) {
		X509_EXTENSION	*ext = NULL;
		GENERAL_NAMES	*names = NULL;
		int		i;

		ext = X509_get_ext(cert, loc);
		if (ext && (names = X509V3_EXT_d2i(ext))) {
			for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
				GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);

				switch (name->type) {
#ifdef GEN_EMAIL
				case GEN_EMAIL: {
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
					char const *rfc822Name = (char const *)ASN1_STRING_get0_data(name->d.rfc822Name);
#else
					char *rfc822Name = (char *)ASN1_STRING_data(name->d.rfc822Name);
#endif

					CERT_ATTR_ADD(IDX_SUBJECT_ALT_NAME_EMAIL, attr_index, rfc822Name);
					break;
				}
#endif	/* GEN_EMAIL */
#ifdef GEN_DNS
				case GEN_DNS: {
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
					char const *dNSName = (char const *)ASN1_STRING_get0_data(name->d.dNSName);
#else
					char *dNSName = (char *)ASN1_STRING_data(name->d.dNSName);
#endif
					CERT_ATTR_ADD(IDX_SUBJECT_ALT_NAME_DNS, attr_index, dNSName);
					break;
				}
#endif	/* GEN_DNS */
#ifdef GEN_OTHERNAME
				case GEN_OTHERNAME:
					/* look for a MS UPN */
					if (NID_ms_upn != OBJ_obj2nid(name->d.otherName->type_id)) break;

					/* we've got a UPN - Must be ASN1-encoded UTF8 string */
					if (name->d.otherName->value->type == V_ASN1_UTF8STRING) {
						CERT_ATTR_ADD(IDX_SUBJECT_ALT_NAME_UPN, attr_index,
								  (char *)name->d.otherName->value->value.utf8string);
						break;
					}

					RWARN("Invalid UPN in Subject Alt Name (should be UTF-8)");
					break;
#endif	/* GEN_OTHERNAME */
				default:
					/* XXX TODO handle other SAN types */
					break;
				}
			}
		}
		if (names != NULL) GENERAL_NAMES_free(names);
	}

	/*
	 *	Only add extensions for the actual client certificate
	 */
	if (attr_index == 0) {
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
		ext_list = X509_get0_extensions(cert);
#else
		ext_list = cert->cert_info->extensions;
#endif

		/*
		 *	Grab the X509 extensions, and create attributes out of them.
		 *	For laziness, we re-use the OpenSSL names
		 */
		if (sk_X509_EXTENSION_num(ext_list) > 0) {
			int i, len;
			char *p;
			BIO *out;

			out = BIO_new(BIO_s_mem());
			strlcpy(attribute, "TLS-Client-Cert-", sizeof(attribute));

			for (i = 0; i < sk_X509_EXTENSION_num(ext_list); i++) {
				char			value[1024];
				ASN1_OBJECT		*obj;
				X509_EXTENSION		*ext;
				fr_dict_attr_t const	*da;

				ext = sk_X509_EXTENSION_value(ext_list, i);

				obj = X509_EXTENSION_get_object(ext);
				i2a_ASN1_OBJECT(out, obj);

				len = BIO_read(out, attribute + 16 , sizeof(attribute) - 16 - 1);
				if (len <= 0) continue;

				attribute[16 + len] = '\0';

				for (p = attribute + 16; *p != '\0'; p++) if (*p == ' ') *p = '-';

				X509V3_EXT_print(out, ext, 0, 0);
				len = BIO_read(out, value , sizeof(value) - 1);
				if (len <= 0) continue;

				value[len] = '\0';

				da = fr_dict_attr_by_name(dict_freeradius, attribute);
				if (!da) {
					RWDEBUG3("Skipping attribute %s: "
						 "Add dictionary definition if you want to access it", attribute);
					continue;
				}

				MEM(vp = fr_pair_afrom_da(request, da));
				if (fr_pair_value_from_str(vp, value, -1, '\0', true) < 0) {
					RPWDEBUG3("Skipping: %s += '%s'", attribute, value);
					talloc_free(vp);
					continue;
				}

				fr_cursor_append(cursor, vp);
			}
			BIO_free_all(out);
		}
	}

	return 0;
}
Ejemplo n.º 14
0
int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags,
                      unsigned long cflag)
{
    long l;
    int i;
    EVP_PKEY *pkey;
    STACK_OF(X509_EXTENSION) *exts;
    char mlch = ' ';
    int nmindent = 0;

    if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
        mlch = '\n';
        nmindent = 12;
    }

    if (nmflags == X509_FLAG_COMPAT)
        nmindent = 16;

    if (!(cflag & X509_FLAG_NO_HEADER)) {
        if (BIO_write(bp, "Certificate Request:\n", 21) <= 0)
            goto err;
        if (BIO_write(bp, "    Data:\n", 10) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_VERSION)) {
        l = X509_REQ_get_version(x);
        if (l >= 0 && l <= 2) {
            if (BIO_printf(bp, "%8sVersion: %ld (0x%lx)\n", "", l + 1, (unsigned long)l) <= 0)
                goto err;
        } else {
            if (BIO_printf(bp, "%8sVersion: Unknown (%ld)\n", "", l) <= 0)
                goto err;
        }
    }
    if (!(cflag & X509_FLAG_NO_SUBJECT)) {
        if (BIO_printf(bp, "        Subject:%c", mlch) <= 0)
            goto err;
        if (X509_NAME_print_ex(bp, X509_REQ_get_subject_name(x),
            nmindent, nmflags) < 0)
            goto err;
        if (BIO_write(bp, "\n", 1) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_PUBKEY)) {
        X509_PUBKEY *xpkey;
        ASN1_OBJECT *koid;
        if (BIO_write(bp, "        Subject Public Key Info:\n", 33) <= 0)
            goto err;
        if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
            goto err;
        xpkey = X509_REQ_get_X509_PUBKEY(x);
        X509_PUBKEY_get0_param(&koid, NULL, NULL, NULL, xpkey);
        if (i2a_ASN1_OBJECT(bp, koid) <= 0)
            goto err;
        if (BIO_puts(bp, "\n") <= 0)
            goto err;

        pkey = X509_REQ_get0_pubkey(x);
        if (pkey == NULL) {
            if (BIO_printf(bp, "%12sUnable to load Public Key\n", "") <= 0)
                goto err;
            ERR_print_errors(bp);
        } else {
            if (EVP_PKEY_print_public(bp, pkey, 16, NULL) <= 0)
                goto err;
        }
    }

    if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) {
        /* may not be */
        if (BIO_printf(bp, "%8sAttributes:\n", "") <= 0)
            goto err;

        if (X509_REQ_get_attr_count(x) == 0) {
            if (BIO_printf(bp, "%12sa0:00\n", "") <= 0)
                goto err;
        } else {
            for (i = 0; i < X509_REQ_get_attr_count(x); i++) {
                ASN1_TYPE *at;
                X509_ATTRIBUTE *a;
                ASN1_BIT_STRING *bs = NULL;
                ASN1_OBJECT *aobj;
                int j, type = 0, count = 1, ii = 0;

                a = X509_REQ_get_attr(x, i);
                aobj = X509_ATTRIBUTE_get0_object(a);
                if (X509_REQ_extension_nid(OBJ_obj2nid(aobj)))
                    continue;
                if (BIO_printf(bp, "%12s", "") <= 0)
                    goto err;
                if ((j = i2a_ASN1_OBJECT(bp, aobj)) > 0) {
                    ii = 0;
                    count = X509_ATTRIBUTE_count(a);
 get_next:
                    at = X509_ATTRIBUTE_get0_type(a, ii);
                    type = at->type;
                    bs = at->value.asn1_string;
                }
                for (j = 25 - j; j > 0; j--)
                    if (BIO_write(bp, " ", 1) != 1)
                        goto err;
                if (BIO_puts(bp, ":") <= 0)
                    goto err;
                switch (type) {
                case V_ASN1_PRINTABLESTRING:
                case V_ASN1_T61STRING:
                case V_ASN1_NUMERICSTRING:
                case V_ASN1_UTF8STRING:
                case V_ASN1_IA5STRING:
                    if (BIO_write(bp, (char *)bs->data, bs->length)
                            != bs->length)
                        goto err;
                    if (BIO_puts(bp, "\n") <= 0)
                        goto err;
                    break;
                default:
                    if (BIO_puts(bp, "unable to print attribute\n") <= 0)
                        goto err;
                    break;
                }
                if (++ii < count)
                    goto get_next;
            }
        }
    }
    if (!(cflag & X509_FLAG_NO_EXTENSIONS)) {
        exts = X509_REQ_get_extensions(x);
        if (exts) {
            if (BIO_printf(bp, "%8sRequested Extensions:\n", "") <= 0)
                goto err;
            for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
                ASN1_OBJECT *obj;
                X509_EXTENSION *ex;
                int critical;
                ex = sk_X509_EXTENSION_value(exts, i);
                if (BIO_printf(bp, "%12s", "") <= 0)
                    goto err;
                obj = X509_EXTENSION_get_object(ex);
                if (i2a_ASN1_OBJECT(bp, obj) <= 0)
                    goto err;
                critical = X509_EXTENSION_get_critical(ex);
                if (BIO_printf(bp, ": %s\n", critical ? "critical" : "") <= 0)
                    goto err;
                if (!X509V3_EXT_print(bp, ex, cflag, 16)) {
                    if (BIO_printf(bp, "%16s", "") <= 0
                        || ASN1_STRING_print(bp,
                                             X509_EXTENSION_get_data(ex)) <= 0)
                        goto err;
                }
                if (BIO_write(bp, "\n", 1) <= 0)
                    goto err;
            }
            sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
        }
    }

    if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
        const X509_ALGOR *sig_alg;
        const ASN1_BIT_STRING *sig;
        X509_REQ_get0_signature(x, &sig, &sig_alg);
        if (!X509_signature_print(bp, sig_alg, sig))
            goto err;
    }

    return 1;
 err:
    X509err(X509_F_X509_REQ_PRINT_EX, ERR_R_BUF_LIB);
    return 0;
}