Exemple #1
1
void *X509V3_EXT_d2i(X509_EXTENSION *ext)
{
    const X509V3_EXT_METHOD *method;
    const unsigned char *p;
    ASN1_STRING *extvalue;
    int extlen;

    if ((method = X509V3_EXT_get(ext)) == NULL)
        return NULL;
    extvalue = X509_EXTENSION_get_data(ext);
    p = ASN1_STRING_get0_data(extvalue);
    extlen = ASN1_STRING_length(extvalue);
    if (method->it)
        return ASN1_item_d2i(NULL, &p, extlen, ASN1_ITEM_ptr(method->it));
    return method->d2i(NULL, &p, extlen);
}
/**
 * Get X509 certificate basic constraints
 *
 * @returns iprt status code.
 *
 * @param   pvBuf                 string representation
 *                                containing X509 certificate
 *                                in PEM format
 * @param   cbSize                The amount of data (in bytes)
 * @param   pBasicConstraintsOut  memory buffer where the
 *                                extracted basic constraints
 *                                will be stored in string
 *                                representation
 */
static int RTX509GetBasicConstraints(void *pvBuf, unsigned int cbSize, unsigned char** pBasicConstraintsOut)
{
    int rc = VINF_SUCCESS;
    BUF_MEM *bptr = NULL;
    X509 *certificate = NULL;
    char *errDesc = NULL;
    BIO *bio_memory = NULL;

    for (;;)
    {
        rc = rtX509ReadCertificateFromPEM(pvBuf, cbSize, &certificate);
        int loc = X509_get_ext_by_NID(certificate, NID_basic_constraints,-1);

        if(loc == -1)
        {
            rc = VERR_X509_NO_BASIC_CONSTARAINTS;
            break;
        }

        X509_EXTENSION *ext = X509_get_ext(certificate, loc);
        if(!ext)
        {
            rc = VERR_X509_GETTING_EXTENSION_FROM_CERT;
            break;
        }

        ASN1_OCTET_STRING *extdata = X509_EXTENSION_get_data(ext);
        if(!extdata)
        {
            rc = VERR_X509_GETTING_DATA_FROM_EXTENSION;
            break;
        }

        bio_memory = BIO_new(BIO_s_mem());
        if(!X509V3_EXT_print(bio_memory, ext, 0, 0))
        {
            rc = VERR_X509_PRINT_EXTENSION_TO_BIO;
            break;
        }
        BIO_ctrl(bio_memory,BIO_CTRL_FLUSH,0,NULL);
        BIO_ctrl(bio_memory,BIO_C_GET_BUF_MEM_PTR,0,(void *)&bptr);

        // now bptr contains the strings of the key_usage
        unsigned char *buf = (unsigned char *)RTMemAlloc((bptr->length + 1)*sizeof(char));
        memcpy(buf, bptr->data, bptr->length);
        // take care that bptr->data is NOT NULL terminated, so add '\0'
        buf[bptr->length] = '\0';

        *pBasicConstraintsOut = buf;

        break;
    }

    if(certificate)
        X509_free(certificate);

    BIO_free(bio_memory);

    return rc;
}
Exemple #3
0
END_TEST

START_TEST(ssl_key_identifier_sha1_01)
{
	X509 *c;
	EVP_PKEY *k;
	unsigned char keyid[SSL_KEY_IDSZ];

	c = ssl_x509_load(TESTCERT);
	fail_unless(!!c, "loading certificate failed");
	k = ssl_key_load(TESTKEY);
	fail_unless(!!k, "loading key failed");

	fail_unless(ssl_key_identifier_sha1(k, keyid) == 0,
	            "ssl_key_identifier_sha1() failed");

	int loc = X509_get_ext_by_NID(c, NID_subject_key_identifier, -1);
	X509_EXTENSION *ext = X509_get_ext(c, loc);
	fail_unless(!!ext, "loading ext failed");
	ASN1_STRING *value = X509_EXTENSION_get_data(ext);
	fail_unless(ASN1_STRING_length(value) - 2 == SSL_KEY_IDSZ,
	             "extension length mismatch");
	fail_unless(!memcmp(ASN1_STRING_get0_data(value) + 2, keyid, SSL_KEY_IDSZ),
	            "key id mismatch");
	EVP_PKEY_free(k);
	X509_free(c);
}
Exemple #4
0
static int openssl_xext_data(lua_State* L)
{
  X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension");
  if(lua_isnone(L, 2)){
    ASN1_STRING *s = X509_EXTENSION_get_data(x);
    PUSH_OBJECT(ASN1_STRING_dup(s),"openssl.asn1_string");
    return 1;
  } else {
    ASN1_STRING *s = CHECK_OBJECT(2, ASN1_STRING, "openssl.asn1_string");
    int ret;
    s = ASN1_STRING_dup(s);
    ret = X509_EXTENSION_set_data(x, s);
    return openssl_pushresult(L, ret);
  }
};
Exemple #5
0
IoObject *IoCertificate_extensions(IoCertificate *self, IoObject *locals, IoMessage *m)
{
	IoObject *map = IoObject_new(IoObject_state(self));
	int i;
	for(i = 0; i < X509_get_ext_count(X509(self)); i++)
	{
		IoObject *ioext = IoObject_new(IoObject_state(self));
		X509_EXTENSION *ext = X509_get_ext(X509(self), i);
		const char *key = (const char *)OBJ_nid2ln(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
		const char *value = (const char *)ASN1_STRING_data(X509_EXTENSION_get_data(ext));
		int isCritical = X509_EXTENSION_get_critical(ext);
		IoObject_setSlot_to_(ioext, IOSYMBOL("value"), IoSeq_newWithCString_(IoObject_state(self), value));
		IoObject_setSlot_to_(ioext, IOSYMBOL("isCritical"), IONUMBER(isCritical));
		IoObject_setSlot_to_(map, IOSYMBOL(key), ioext);
	}
	return map;
}
Exemple #6
0
/*
 * Modifies a certificate by deleting extensions and copying the issuer and
 * AKID from the presigner certificate, if necessary.
 * Returns 1 on success, 0 otherwise.
 */
__owur static int ct_x509_cert_fixup(X509 *cert, X509 *presigner)
{
    int preidx, certidx;
    int pre_akid_ext_is_dup, cert_akid_ext_is_dup;

    if (presigner == NULL)
        return 1;

    preidx = ct_x509_get_ext(presigner, NID_authority_key_identifier,
                             &pre_akid_ext_is_dup);
    certidx = ct_x509_get_ext(cert, NID_authority_key_identifier,
                              &cert_akid_ext_is_dup);

    /* An error occurred whilst searching for the extension */
    if (preidx < -1 || certidx < -1)
        return 0;
    /* Invalid certificate if they contain duplicate extensions */
    if (pre_akid_ext_is_dup || cert_akid_ext_is_dup)
        return 0;
    /* AKID must be present in both certificate or absent in both */
    if (preidx >= 0 && certidx == -1)
        return 0;
    if (preidx == -1 && certidx >= 0)
        return 0;
    /* Copy issuer name */
    if (!X509_set_issuer_name(cert, X509_get_issuer_name(presigner)))
        return 0;
    if (preidx != -1) {
        /* Retrieve and copy AKID encoding */
        X509_EXTENSION *preext = X509_get_ext(presigner, preidx);
        X509_EXTENSION *certext = X509_get_ext(cert, certidx);
        ASN1_OCTET_STRING *preextdata;

        /* Should never happen */
        if (preext == NULL || certext == NULL)
            return 0;
        preextdata = X509_EXTENSION_get_data(preext);
        if (preextdata == NULL ||
            !X509_EXTENSION_set_data(certext, preextdata))
            return 0;
    }
    return 1;
}
Exemple #7
0
static int openssl_xext_data(lua_State* L)
{
  int ret = 0;
  X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension");
  if (lua_isnone(L, 2))
  {
    ASN1_STRING *s = X509_EXTENSION_get_data(x);
    s = ASN1_STRING_dup(s);
    PUSH_OBJECT(s, "openssl.asn1_string");
    return 1;
  }
  else if (lua_isstring(L, 2))
  {
    size_t size;
    const char* data = lua_tolstring(L, 2, &size);
    ASN1_STRING* s = ASN1_STRING_type_new(V_ASN1_OCTET_STRING);
    if (ASN1_STRING_set(s, data, size) == 1)
    {
      ret = X509_EXTENSION_set_data(x, s);
    }
    ASN1_STRING_free(s);
    return openssl_pushresult(L, ret);
  }
  else
  {
    ASN1_STRING* s = CHECK_GROUP(2, ASN1_STRING, "openssl.asn1group");
    if (ASN1_STRING_type(s) == V_ASN1_OCTET_STRING)
    {
      int ret;
      ret = X509_EXTENSION_set_data(x, s);
      return openssl_pushresult(L, ret);
    }
    else
    {
      luaL_argerror(L, 2, "asn1_string type must be octet");
    }
  }
  return 0;
};
Exemple #8
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;
}
Exemple #9
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);
}
Exemple #10
0
extern "C" ASN1_OCTET_STRING* CryptoNative_X509ExtensionGetData(X509_EXTENSION* x)
{
    return X509_EXTENSION_get_data(x);
}
/**
 * @brief Inquire Sec Context by OID
 * @ingroup globus_gsi_gssapi_extensions
 */
OM_uint32
GSS_CALLCONV gss_inquire_sec_context_by_oid(
    OM_uint32 *                         minor_status,
    const gss_ctx_id_t                  context_handle,
    const gss_OID                       desired_object,
    gss_buffer_set_t *                  data_set)
{
    OM_uint32                           major_status = GSS_S_COMPLETE;
    OM_uint32                           local_minor_status;
    gss_ctx_id_desc *                   context = NULL;
    int                                 found_index;
    int                                 chain_index;
    int                                 cert_count;
    X509_EXTENSION *                    extension;
    X509 *                              cert = NULL;
    STACK_OF(X509) *                    cert_chain = NULL;
    ASN1_OBJECT *                       asn1_desired_obj = NULL;
    ASN1_OCTET_STRING *                 asn1_oct_string;
    gss_buffer_desc                     data_set_buffer = GSS_C_EMPTY_BUFFER;
    globus_result_t                     local_result = GLOBUS_SUCCESS;
    unsigned char *                     tmp_ptr;
    static char *                       _function_name_ =
        "gss_inquire_sec_context_by_oid";
    GLOBUS_I_GSI_GSSAPI_DEBUG_ENTER;

    /* parameter checking goes here */

    if(minor_status == NULL)
    {
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("Invalid minor_status (NULL) passed to function")));
        major_status = GSS_S_FAILURE;
        goto exit;
    }
    
    if(context_handle == GSS_C_NO_CONTEXT)
    {
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("Invalid context_handle passed to function")));
        major_status = GSS_S_FAILURE;
        goto exit;
    }

    *minor_status = (OM_uint32) GLOBUS_SUCCESS;
    context = (gss_ctx_id_desc *) context_handle;

    if(desired_object == GSS_C_NO_OID)
    {
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("Invalid desired_object passed to function")));
        major_status = GSS_S_FAILURE;
        goto exit;
    }

    if(data_set == NULL)
    {
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("Invalid data_set (NULL) passed to function")));
        major_status = GSS_S_FAILURE;
        goto exit;
    }

    *data_set = NULL;

    /* lock the context mutex */
    globus_mutex_lock(&context->mutex);

    local_result = 
        globus_gsi_callback_get_cert_depth(context->callback_data,
                                           &cert_count);
    if(local_result != GLOBUS_SUCCESS)
    {
        GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
            minor_status, local_result,
            GLOBUS_GSI_GSSAPI_ERROR_WITH_CALLBACK_DATA);
        major_status = GSS_S_FAILURE;
        goto unlock_exit;
    }

    if(cert_count == 0)
    {
        goto unlock_exit;
    }
    
    major_status = gss_create_empty_buffer_set(&local_minor_status, data_set);

    if(GSS_ERROR(major_status))
    {
        GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
            minor_status, local_minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_WITH_BUFFER);
        goto unlock_exit;
    }
    
    local_result = globus_gsi_callback_get_cert_chain(
        context->callback_data,
        &cert_chain);
    if(local_result != GLOBUS_SUCCESS)
    {
        GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
            minor_status, local_result,
            GLOBUS_GSI_GSSAPI_ERROR_WITH_CALLBACK_DATA);
        major_status = GSS_S_FAILURE;
        cert_chain = NULL;
        goto unlock_exit;
    }

    if(((gss_OID_desc *)desired_object)->length !=
       gss_ext_x509_cert_chain_oid->length ||
       memcmp(((gss_OID_desc *)desired_object)->elements,
              gss_ext_x509_cert_chain_oid->elements,
              gss_ext_x509_cert_chain_oid->length))
    {
        /* figure out what object was asked for */
        
        asn1_desired_obj = ASN1_OBJECT_new();
        if(!asn1_desired_obj)
        {
            GLOBUS_GSI_GSSAPI_OPENSSL_ERROR_RESULT(
                minor_status,
                GLOBUS_GSI_GSSAPI_ERROR_WITH_OPENSSL,
                (_GGSL("Couldn't create ASN1 object")));
            major_status = GSS_S_FAILURE;
            goto unlock_exit;
        }

        asn1_desired_obj->length = ((gss_OID_desc *)desired_object)->length;
        asn1_desired_obj->data = ((gss_OID_desc *)desired_object)->elements;

        found_index = -1;

        for(chain_index = 0; chain_index < cert_count; chain_index++)
        {
            cert = sk_X509_value(cert_chain, chain_index);

            data_set_buffer.value = NULL;
            data_set_buffer.length = 0;

            found_index = X509_get_ext_by_OBJ(cert, 
                                              asn1_desired_obj, 
                                              found_index);
        
            if(found_index >= 0)
            {
                extension = X509_get_ext(cert, found_index);
                if(!extension)
                {
                    GLOBUS_GSI_GSSAPI_OPENSSL_ERROR_RESULT(
                        minor_status,
                        GLOBUS_GSI_GSSAPI_ERROR_WITH_OPENSSL,
                        (_GGSL("Couldn't get extension at index %d "
                         "from cert in credential."), found_index));
                    major_status = GSS_S_FAILURE;
                    goto unlock_exit;
                }

                asn1_oct_string = X509_EXTENSION_get_data(extension);
                if(!asn1_oct_string)
                {
                    GLOBUS_GSI_GSSAPI_OPENSSL_ERROR_RESULT(
                        minor_status,
                        GLOBUS_GSI_GSSAPI_ERROR_WITH_OPENSSL,
                        (_GGSL("Couldn't get cert extension in the form of an "
                         "ASN1 octet string.")));
                    major_status = GSS_S_FAILURE;
                    goto unlock_exit;
                }

                asn1_oct_string = ASN1_OCTET_STRING_dup(asn1_oct_string);

                if(!asn1_oct_string)
                {
                    GLOBUS_GSI_GSSAPI_OPENSSL_ERROR_RESULT(
                        minor_status,
                        GLOBUS_GSI_GSSAPI_ERROR_WITH_OPENSSL,
                        (_GGSL("Failed to make copy of extension data")));
                    major_status = GSS_S_FAILURE;
                    goto unlock_exit;
                }

                data_set_buffer.value = asn1_oct_string->data;
                data_set_buffer.length = asn1_oct_string->length;

                OPENSSL_free(asn1_oct_string);
            
                major_status = gss_add_buffer_set_member(
                    &local_minor_status,
                    &data_set_buffer,
                    data_set);
                if(GSS_ERROR(major_status))
                {
                    GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
                        minor_status, local_minor_status,
                        GLOBUS_GSI_GSSAPI_ERROR_WITH_BUFFER);
                    goto unlock_exit;
                }
            }
        } 
    }
    else
    {
        for(chain_index = 0; chain_index < cert_count; chain_index++)
        {
            int certlen;
            cert = sk_X509_value(cert_chain, chain_index);

            certlen = i2d_X509(cert, NULL);
            data_set_buffer.length = certlen;

            if (certlen < 0)
            {
                GLOBUS_GSI_GSSAPI_OPENSSL_ERROR_RESULT(
                    minor_status,
                    GLOBUS_GSI_GSSAPI_ERROR_WITH_OPENSSL,
                    (_GGSL("Failed to serialize certificate")));
                major_status = GSS_S_FAILURE;
                goto unlock_exit;                
            }
            
            tmp_ptr = realloc(data_set_buffer.value,
                              data_set_buffer.length);

            if(tmp_ptr == NULL)
            {
                GLOBUS_GSI_GSSAPI_MALLOC_ERROR(minor_status);
                major_status = GSS_S_FAILURE;
                goto unlock_exit;                
            }

            data_set_buffer.value = tmp_ptr;
            
            if(i2d_X509(cert,&tmp_ptr) < 0)
            {
                free(data_set_buffer.value);
                GLOBUS_GSI_GSSAPI_OPENSSL_ERROR_RESULT(
                    minor_status,
                    GLOBUS_GSI_GSSAPI_ERROR_WITH_OPENSSL,
                    (_GGSL("Failed to serialize certificate")));
                major_status = GSS_S_FAILURE;
                goto unlock_exit;                
            }

            major_status = gss_add_buffer_set_member(
                &local_minor_status,
                &data_set_buffer,
                data_set);
            if(GSS_ERROR(major_status))
            {
                GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
                    minor_status, local_minor_status,
                    GLOBUS_GSI_GSSAPI_ERROR_WITH_BUFFER);
                goto unlock_exit;
            }
        }
        
        if(data_set_buffer.value != NULL)
        {
            free(data_set_buffer.value);
        }
    }

unlock_exit:
    /* unlock the context mutex */
    globus_mutex_unlock(&context->mutex);

exit:
    if (asn1_desired_obj != NULL)
    {
        ASN1_OBJECT_free(asn1_desired_obj);
    }
    if(cert_chain != NULL)
    {
        sk_X509_pop_free(cert_chain, X509_free);
    }
    
    GLOBUS_I_GSI_GSSAPI_DEBUG_EXIT;
    return major_status;
}
Exemple #12
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;
}
Exemple #13
0
		inline asn1::string extension::data() const
		{
			return X509_EXTENSION_get_data(ptr().get());
		}
Exemple #14
0
int
globus_i_gram_get_tg_gateway_user(
    gss_ctx_id_t                        context,
    globus_gsi_cred_handle_t            peer_cred,
    char **                             gateway_user)
{
#if HAVE_LIBXML2
    OM_uint32                           maj_stat, min_stat;
    gss_buffer_set_t                    data_set;
    ASN1_UTF8STRING *                   asn1_str;
    char *                              assertion_string;
    unsigned char *                     p;
    long                                pl;
    xmlDocPtr                           doc;
    xmlXPathContextPtr                  xpath_ctx;
    xmlXPathObjectPtr                   xresult;
    int                                 rc;
    ASN1_OBJECT *                       asn1_desired_object = NULL;
    int                                 cert_count;
    int                                 found_index;
    int                                 chain_index;
    X509                               *cert;
    X509_EXTENSION *                    extension;
    ASN1_OCTET_STRING                  *asn1_oct_string;
    STACK_OF(X509)                     *chain = NULL;

    *gateway_user = NULL;

    if (context == GSS_C_NO_CONTEXT && peer_cred != NULL)
    {
        globus_result_t result;
        /* This basically duplicates the gss_inquire_sec_context_by_oid(), but
         * instead uses a gsi credential object
         */
        rc = GLOBUS_SUCCESS;
        asn1_desired_object = ASN1_OBJECT_new();
        if (asn1_desired_object == NULL)
        {
            rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;
            goto no_extension_in_cred_chain;
        }

        asn1_desired_object->length = globus_l_saml_oid_desc.length;
        asn1_desired_object->data = globus_l_saml_oid_desc.elements;

        result = globus_gsi_cred_get_cert_chain(peer_cred, &chain);
        if (result != GLOBUS_SUCCESS)
        {
            char * msg;
            
            msg = globus_error_print_friendly(
                globus_error_peek(result));
            globus_gram_protocol_error_7_hack_replace_message(
                    msg);

            free(msg);
            rc = GLOBUS_GRAM_PROTOCOL_ERROR_AUTHORIZATION;

            goto no_extension_in_cred_chain;
        }

        cert_count = sk_X509_num(chain);
        found_index = -1;
        for (chain_index = 0; chain_index < cert_count; chain_index++)
        {
            cert = sk_X509_value(chain, chain_index);
            found_index = X509_get_ext_by_OBJ(cert, asn1_desired_object, found_index);
            if (found_index >= 0)
            {
                extension = X509_get_ext(cert, found_index);
                if (extension == NULL)
                {
                    rc = GLOBUS_GRAM_PROTOCOL_ERROR_AUTHORIZATION;
                    globus_gram_protocol_error_7_hack_replace_message(
                        "Unable to extract SAML assertion extension from certificate chain");
                    goto no_extension_in_cred_chain;
                }
                asn1_oct_string = X509_EXTENSION_get_data(extension);
                if (asn1_oct_string == NULL)
                {
                    rc = GLOBUS_GRAM_PROTOCOL_ERROR_AUTHORIZATION;
                    globus_gram_protocol_error_7_hack_replace_message(
                        "Unable to extract SAML assertion extension from certificate chain");
                    goto no_extension_in_cred_chain;
                }
                p = asn1_oct_string->data;

                asn1_str = d2i_ASN1_UTF8STRING(NULL, (void *)&p, asn1_oct_string->length);
                if (asn1_str == NULL)
                {
                    rc = GLOBUS_GRAM_PROTOCOL_ERROR_AUTHORIZATION;
                    globus_gram_protocol_error_7_hack_replace_message(
                        "Unable to convert SAML assertion text from DER to UTF8");
                    goto no_extension_in_cred_chain;
                }
                assertion_string = malloc(asn1_str->length + 1);
                if (assertion_string == NULL)
                {
                    rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;
                    goto no_extension_in_cred_chain;
                }
                memcpy(assertion_string, asn1_str->data, asn1_str->length);
                assertion_string[asn1_str->length] = 0;
                break;
            }
        }
        if (chain_index == cert_count)
        {
            goto no_extension_in_cred_chain;
        }
    }
    else if (context == GSS_C_NO_CONTEXT)
    {
        rc = GLOBUS_SUCCESS;
        goto no_context;
    }
    else
    {
        maj_stat =  gss_inquire_sec_context_by_oid(
                &min_stat,
                context,
                globus_saml_oid,
                &data_set);

        if (GSS_ERROR(maj_stat))
        {
            globus_gram_protocol_error_7_hack_replace_message(
                    "Error extracting SAML assertion");

            rc = GLOBUS_GRAM_PROTOCOL_ERROR_AUTHORIZATION;

            goto inquire_failed;
        }

        /* We'll process only the first SAML assertion bound in the X.509 chain */
        if (data_set->count < 1)
        {
            rc = GLOBUS_SUCCESS;

            goto empty_data_set;
        }

        p = data_set->elements[0].value;
        pl = data_set->elements[0].length;

        /* Convert DER-Encoded string to UTF8 */
        asn1_str = d2i_ASN1_UTF8STRING(NULL, (void *) &p, pl);
        if (!asn1_str)
        {
            globus_gram_protocol_error_7_hack_replace_message(
                    "Error decoding SAML assertion");
            rc = GLOBUS_GRAM_PROTOCOL_ERROR_AUTHORIZATION;

            goto utfstring_failed;
        }

        assertion_string = malloc(asn1_str->length + 1);
        if (assertion_string == NULL)
        {
            rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;

            goto assertion_string_malloc_failed;
        }
        memcpy(assertion_string, asn1_str->data, asn1_str->length);
        assertion_string[asn1_str->length] = 0;
    }

    /* Parse SAML assertion */
    doc = xmlParseDoc(BAD_CAST assertion_string);
    if (doc == NULL)
    {
        globus_gram_protocol_error_7_hack_replace_message(
                "Error parsing SAML assertion");
        rc = GLOBUS_GRAM_PROTOCOL_ERROR_AUTHORIZATION;

        goto parse_assertion_failed;
    }

    xmlXPathInit();

    /* Use XPATH to extract Issuer */
    xpath_ctx = xmlXPathNewContext(doc);
    if (xpath_ctx == NULL)
    {
        rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;

        goto xpath_ctx_init_failed;
    }
    rc = xmlXPathRegisterNs(
            xpath_ctx,
            (xmlChar *) "s",
            (xmlChar *) "urn:oasis:names:tc:SAML:1.0:assertion");

    if (rc != 0)
    {
        rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;

        goto xpath_register_ns_failed;
    }

    xresult = xmlXPathEvalExpression(
            (const xmlChar *) "string(/s:Assertion/@Issuer)",
            xpath_ctx);

    if (xresult == NULL)
    {
        globus_gram_protocol_error_7_hack_replace_message(
                "Error processing SAML assertion: no \"Issuer\" attribute");
        rc = GLOBUS_GRAM_PROTOCOL_ERROR_AUTHORIZATION;

        goto xpath_eval_issuer_failed;
    }

    if (! globus_l_tg_saml_assertion_is_self_issued(
                context,
                (const char *) xresult->stringval))
    {
        /* Ignore non-self issued assertions */
        rc = GLOBUS_SUCCESS;

        goto non_self_issued;
    }

    xmlXPathFreeObject(xresult);

    /* Use XPATH to extract the sender-vouches, self-issued, TG principal name
     * Subject attribute from the Assertion's AuthenticationStatement
     */
    xresult = xmlXPathEvalExpression(
            (const xmlChar *) "string(/s:Assertion/s:AuthenticationStatement/s:Subject[string(s:SubjectConfirmation/s:ConfirmationMethod) = 'urn:oasis:names:tc:SAML:1.0:cm:sender-vouches' and s:NameIdentifier/@Format = 'http://teragrid.org/names/nameid-format/principalname']/s:NameIdentifier[1])",
            xpath_ctx);

    if (xresult == NULL)
    {
        globus_gram_protocol_error_7_hack_replace_message(
                "Error processing SAML assertion: no teragrid principal");
        rc = GLOBUS_GRAM_PROTOCOL_ERROR_AUTHORIZATION;

        goto get_gateway_name_failed;
    }

    if (xresult != NULL &&
        xresult->stringval != NULL &&
        *(xresult->stringval) != 0)
    {
        *gateway_user = strdup((char *) xresult->stringval);
    }

get_gateway_name_failed:
non_self_issued:
    if (xresult != NULL)
    {
        xmlXPathFreeObject(xresult);
    }
xpath_eval_issuer_failed:
xpath_register_ns_failed:
    xmlXPathFreeContext(xpath_ctx);
xpath_ctx_init_failed:
    xmlFreeDoc(doc);
parse_assertion_failed:
    free(assertion_string);
assertion_string_malloc_failed:
    ASN1_UTF8STRING_free(asn1_str);
utfstring_failed:
empty_data_set:
    gss_release_buffer_set(&min_stat, &data_set);
inquire_failed:
no_extension_in_cred_chain:
no_context:
    if (asn1_desired_object != NULL)
    {
        ASN1_OBJECT_free(asn1_desired_object);
    }
    if (chain != NULL)
    {
        sk_X509_free(chain);
    }
    return rc;
#else
    *gateway_user = NULL;
    return GLOBUS_SUCCESS;
#endif /* HAVE_LIBXML2 */
}