提交 61d81f0a 编写于 作者: R Richard Levitte

Update the example in proxy_certificates.txt

Reviewed-by: NRich Salz <rsalz@openssl.org>
上级 9d7bfb14
...@@ -164,138 +164,151 @@ You need the following ingredients: ...@@ -164,138 +164,151 @@ You need the following ingredients:
Here is some skeleton code you can fill in: Here is some skeleton code you can fill in:
/* In this example, I will use a view of granted rights as a bit #include <string.h>
array, one bit for each possible right. */ #include <netdb.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#define total_rights 25
/*
* In this example, I will use a view of granted rights as a bit
* array, one bit for each possible right.
*/
typedef struct your_rights { typedef struct your_rights {
unsigned char rights[total_rights / 8]; unsigned char rights[(total_rights + 7) / 8];
} YOUR_RIGHTS; } YOUR_RIGHTS;
/* The following procedure will create an index for the ex_data /*
store in the X509 validation context the first time it's called. * The following procedure will create an index for the ex_data
Subsequent calls will return the same index. */ * store in the X509 validation context the first time it's called.
static int get_proxy_auth_ex_data_idx(void) * Subsequent calls will return the same index. */
static int get_proxy_auth_ex_data_idx(X509_STORE_CTX *ctx)
{ {
static volatile int idx = -1; static volatile int idx = -1;
if (idx < 0) if (idx < 0) {
{ X509_STORE_lock(X509_STORE_CTX_get0_store(ctx));
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); if (idx < 0) {
if (idx < 0) idx = X509_STORE_CTX_get_ex_new_index(0,
{ "for verify callback",
idx = X509_STORE_CTX_get_ex_new_index(0, NULL,NULL,NULL);
"for verify callback",
NULL,NULL,NULL);
} }
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); X509_STORE_unlock(X509_STORE_CTX_get0_store(ctx));
} }
return idx; return idx;
} }
/* Callback to be given to the X509 validation procedure. */ /* Callback to be given to the X509 validation procedure. */
static int verify_callback(int ok, X509_STORE_CTX *ctx) static int verify_callback(int ok, X509_STORE_CTX *ctx)
{ {
if (ok == 1) /* It's REALLY important you keep the proxy policy if (ok == 1) {
check within this section. It's important to know /*
that when ok is 1, the certificates are checked * It's REALLY important you keep the proxy policy
from top to bottom. You get the CA root first, * check within this section. It's important to know
followed by the possible chain of intermediate * that when ok is 1, the certificates are checked
CAs, followed by the EE certificate, followed by * from top to bottom. You get the CA root first,
the possible proxy certificates. */ * followed by the possible chain of intermediate
{ * CAs, followed by the EE certificate, followed by
X509 *xs = ctx->current_cert; * the possible proxy certificates.
*/
if (xs->ex_flags & EXFLAG_PROXY) X509 *xs = X509_STORE_CTX_get_current_cert(ctx);
{
YOUR_RIGHTS *rights = if (X509_get_extension_flags(xs) & EXFLAG_PROXY) {
(YOUR_RIGHTS *)X509_STORE_CTX_get_ex_data(ctx, YOUR_RIGHTS *rights =
get_proxy_auth_ex_data_idx()); (YOUR_RIGHTS *)X509_STORE_CTX_get_ex_data(ctx,
PROXY_CERT_INFO_EXTENSION *pci = get_proxy_auth_ex_data_idx(ctx));
X509_get_ext_d2i(xs, NID_proxyCertInfo, NULL, NULL); PROXY_CERT_INFO_EXTENSION *pci =
X509_get_ext_d2i(xs, NID_proxyCertInfo, NULL, NULL);
switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage))
{ switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage)) {
case NID_Independent: case NID_Independent:
/* Do whatever you need to grant explicit rights to /*
this particular proxy certificate, usually by * Do whatever you need to grant explicit rights to
pulling them from some database. If there are none * this particular proxy certificate, usually by
to be found, clear all rights (making this and any * pulling them from some database. If there are none
subsequent proxy certificate void of any rights). * to be found, clear all rights (making this and any
*/ * subsequent proxy certificate void of any rights).
memset(rights->rights, 0, sizeof(rights->rights)); */
break; memset(rights->rights, 0, sizeof(rights->rights));
break;
case NID_id_ppl_inheritAll: case NID_id_ppl_inheritAll:
/* This is basically a NOP, we simply let the current /*
rights stand as they are. */ * This is basically a NOP, we simply let the current
break; * rights stand as they are.
*/
break;
default: default:
/* This is usually the most complex section of code. /* This is usually the most complex section of code.
You really do whatever you want as long as you * You really do whatever you want as long as you
follow RFC 3820. In the example we use here, the * follow RFC 3820. In the example we use here, the
simplest thing to do is to build another, temporary * simplest thing to do is to build another, temporary
bit array and fill it with the rights granted by * bit array and fill it with the rights granted by
the current proxy certificate, then use it as a * the current proxy certificate, then use it as a
mask on the accumulated rights bit array, and * mask on the accumulated rights bit array, and
voilà, you now have a new accumulated rights bit * voilà, you now have a new accumulated rights bit
array. */ * array.
{ */
int i; {
YOUR_RIGHTS tmp_rights; int i;
memset(tmp_rights.rights, 0, sizeof(tmp_rights.rights)); YOUR_RIGHTS tmp_rights;
memset(tmp_rights.rights, 0, sizeof(tmp_rights.rights));
/* process_rights() is supposed to be a procedure
that takes a string and it's length, interprets /*
it and sets the bits in the YOUR_RIGHTS pointed * process_rights() is supposed to be a procedure
at by the third argument. */ * that takes a string and it's length, interprets
process_rights((char *) pci->proxyPolicy->policy->data, * it and sets the bits in the YOUR_RIGHTS pointed
pci->proxyPolicy->policy->length, * at by the third argument.
&tmp_rights); */
process_rights((char *) pci->proxyPolicy->policy->data,
for(i = 0; i < total_rights / 8; i++) pci->proxyPolicy->policy->length,
rights->rights[i] &= tmp_rights.rights[i]; &tmp_rights);
}
break; for(i = 0; i < total_rights / 8; i++)
rights->rights[i] &= tmp_rights.rights[i];
}
break;
} }
PROXY_CERT_INFO_EXTENSION_free(pci); PROXY_CERT_INFO_EXTENSION_free(pci);
} } else if (!(X509_get_extension_flags(xs) & EXFLAG_CA)) {
else if (!(xs->ex_flags & EXFLAG_CA)) /* We have an EE certificate, let's use it to set default! */
{ YOUR_RIGHTS *rights =
/* We have an EE certificate, let's use it to set default! (YOUR_RIGHTS *)X509_STORE_CTX_get_ex_data(ctx,
*/ get_proxy_auth_ex_data_idx(ctx));
YOUR_RIGHTS *rights =
(YOUR_RIGHTS *)X509_STORE_CTX_get_ex_data(ctx, /* The following procedure finds out what rights the owner
get_proxy_auth_ex_data_idx()); * of the current certificate has, and sets them in the
* YOUR_RIGHTS structure pointed at by the second
/* The following procedure finds out what rights the owner * argument.
of the current certificate has, and sets them in the */
YOUR_RIGHTS structure pointed at by the second set_default_rights(xs, rights);
argument. */
set_default_rights(xs, rights);
} }
} }
return ok; return ok;
} }
static int my_X509_verify_cert(X509_STORE_CTX *ctx, static int my_X509_verify_cert(X509_STORE_CTX *ctx,
YOUR_RIGHTS *needed_rights) YOUR_RIGHTS *needed_rights)
{ {
int i; int ok;
int (*save_verify_cb)(int ok,X509_STORE_CTX *ctx) = ctx->verify_cb; int (*save_verify_cb)(int ok,X509_STORE_CTX *ctx) =
YOUR_RIGHTS rights; X509_STORE_CTX_get_verify_cb(ctx);
YOUR_RIGHTS rights;
X509_STORE_CTX_set_verify_cb(ctx, verify_callback);
X509_STORE_CTX_set_ex_data(ctx, get_proxy_auth_ex_data_idx(), &rights); X509_STORE_CTX_set_verify_cb(ctx, verify_callback);
X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS); X509_STORE_CTX_set_ex_data(ctx, get_proxy_auth_ex_data_idx(ctx), &rights);
ok = X509_verify_cert(ctx); X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
ok = X509_verify_cert(ctx);
if (ok == 1)
{ if (ok == 1) {
ok = check_needed_rights(rights, needed_rights); ok = check_needed_rights(rights, needed_rights);
} }
X509_STORE_CTX_set_verify_cb(ctx, save_verify_cb); X509_STORE_CTX_set_verify_cb(ctx, save_verify_cb);
return ok; return ok;
} }
If you use SSL or TLS, you can easily set up a callback to have the If you use SSL or TLS, you can easily set up a callback to have the
certificates checked properly, using the code above: certificates checked properly, using the code above:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册