提交 7a71af86 编写于 作者: B Ben Laurie

Rearrange and test authz extension.

上级 32e62d1c
......@@ -316,8 +316,6 @@ static int cert_chain = 0;
#ifndef OPENSSL_NO_TLSEXT
static BIO *authz_in = NULL;
static const char *s_authz_file = NULL;
static unsigned char *authz = NULL;
static size_t authz_length;
#endif
#ifndef OPENSSL_NO_PSK
......@@ -1501,33 +1499,6 @@ bad:
next_proto.data = NULL;
}
# endif
if (s_authz_file != NULL)
{
/* Allow authzs up to 64KB bytes. */
static const size_t authz_limit = 65536;
authz_in = BIO_new(BIO_s_file_internal());
if (authz_in == NULL)
{
ERR_print_errors(bio_err);
goto end;
}
if (BIO_read_filename(authz_in, s_authz_file) <= 0)
{
ERR_print_errors(bio_err);
goto end;
}
authz = OPENSSL_malloc(authz_limit);
authz_length = BIO_read(authz_in, authz, authz_limit);
if (authz_length == authz_limit || authz_length <= 0)
{
BIO_printf(bio_err, "authz too large\n");
goto end;
}
BIO_free(authz_in);
authz_in = NULL;
}
#endif /* OPENSSL_NO_TLSEXT */
}
......@@ -1828,7 +1799,7 @@ bad:
if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain))
goto end;
#ifndef OPENSSL_NO_TLSEXT
if (authz != NULL && !SSL_CTX_use_authz(ctx, authz, authz_length))
if (s_authz_file != NULL && !SSL_CTX_use_authz_file(ctx, s_authz_file))
goto end;
#endif
#ifndef OPENSSL_NO_TLSEXT
......@@ -2025,8 +1996,6 @@ end:
X509_free(s_cert2);
if (s_key2)
EVP_PKEY_free(s_key2);
if (authz != NULL)
OPENSSL_free(authz);
if (authz_in != NULL)
BIO_free(authz_in);
#endif
......
......@@ -1782,8 +1782,16 @@ int SSL_use_certificate(SSL *ssl, X509 *x);
int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
#ifndef OPENSSL_NO_TLSEXT
/* Set authz data for the current active cert. */
int SSL_CTX_use_authz(SSL_CTX *ctx, unsigned char *authz, size_t authz_length);
int SSL_use_authz(SSL *ssl, unsigned char *authz, size_t authz_length);
/* Get the authz of type 'type' associated with the current active cert. */
const unsigned char *SSL_CTX_get_authz_data(SSL_CTX *ctx, unsigned char type,
size_t *data_length);
#ifndef OPENSSL_NO_STDIO
int SSL_CTX_use_authz_file(SSL_CTX *ctx, const char *file);
int SSL_use_authz_file(SSL *ssl, const char *file);
#endif
#endif
#ifndef OPENSSL_NO_STDIO
......@@ -2137,6 +2145,7 @@ void ERR_load_SSL_strings(void);
/* Error codes for the SSL functions. */
/* Function codes. */
#define SSL_F_AUTHZ_FIND_DATA 330
#define SSL_F_AUTHZ_VALIDATE 323
#define SSL_F_CLIENT_CERTIFICATE 100
#define SSL_F_CLIENT_FINISHED 167
......@@ -2180,6 +2189,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_GET_SERVER_HELLO 109
#define SSL_F_GET_SERVER_VERIFY 110
#define SSL_F_I2D_SSL_SESSION 111
#define SSL_F_READ_AUTHZ 329
#define SSL_F_READ_N 112
#define SSL_F_REQUEST_CERTIFICATE 113
#define SSL_F_SERVER_FINISH 239
......
......@@ -70,6 +70,7 @@
static ERR_STRING_DATA SSL_str_functs[]=
{
{ERR_FUNC(SSL_F_AUTHZ_FIND_DATA), "AUTHZ_FIND_DATA"},
{ERR_FUNC(SSL_F_AUTHZ_VALIDATE), "AUTHZ_VALIDATE"},
{ERR_FUNC(SSL_F_CLIENT_CERTIFICATE), "CLIENT_CERTIFICATE"},
{ERR_FUNC(SSL_F_CLIENT_FINISHED), "CLIENT_FINISHED"},
......@@ -113,6 +114,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_GET_SERVER_HELLO), "GET_SERVER_HELLO"},
{ERR_FUNC(SSL_F_GET_SERVER_VERIFY), "GET_SERVER_VERIFY"},
{ERR_FUNC(SSL_F_I2D_SSL_SESSION), "i2d_SSL_SESSION"},
{ERR_FUNC(SSL_F_READ_AUTHZ), "READ_AUTHZ"},
{ERR_FUNC(SSL_F_READ_N), "READ_N"},
{ERR_FUNC(SSL_F_REQUEST_CERTIFICATE), "REQUEST_CERTIFICATE"},
{ERR_FUNC(SSL_F_SERVER_FINISH), "SERVER_FINISH"},
......
......@@ -855,6 +855,46 @@ static char authz_validate(const unsigned char *authz, size_t length)
}
}
static const unsigned char *authz_find_data(const unsigned char *authz,
size_t authz_length,
unsigned char data_type,
size_t *data_length)
{
if (authz == NULL) return NULL;
if (!authz_validate(authz, authz_length))
{
SSLerr(SSL_F_AUTHZ_FIND_DATA,SSL_R_INVALID_AUTHZ_DATA);
return NULL;
}
for (;;)
{
unsigned char type;
unsigned short len;
if (!authz_length)
return NULL;
type = *(authz++);
authz_length--;
/* We've validated the authz data, so we don't have to
* check again that we have enough bytes left. */
len = ((unsigned short) authz[0]) << 8 |
((unsigned short) authz[1]);
authz += 2;
authz_length -= 2;
if (type == data_type)
{
*data_length = len;
return authz;
}
authz += len;
authz_length -= len;
}
/* No match */
return NULL;
}
static int ssl_set_authz(CERT *c, unsigned char *authz, size_t authz_length)
{
CERT_PKEY *current_key = c->key;
......@@ -901,4 +941,90 @@ int SSL_use_authz(SSL *ssl, unsigned char *authz, size_t authz_length)
}
return ssl_set_authz(ssl->cert, authz, authz_length);
}
const unsigned char *SSL_CTX_get_authz_data(SSL_CTX *ctx, unsigned char type,
size_t *data_length)
{
CERT_PKEY *current_key;
if (ctx->cert == NULL)
return NULL;
current_key = ctx->cert->key;
if (current_key->authz == NULL)
return NULL;
return authz_find_data(current_key->authz,
current_key->authz_length, type, data_length);
}
#ifndef OPENSSL_NO_STDIO
/* read_authz returns a newly allocated buffer with authz data */
static unsigned char *read_authz(const char *file, size_t *authz_length)
{
BIO *authz_in = NULL;
unsigned char *authz = NULL;
/* Allow authzs up to 64KB. */
static const size_t authz_limit = 65536;
size_t read_length;
unsigned char *ret = NULL;
authz_in = BIO_new(BIO_s_file_internal());
if (authz_in == NULL)
{
SSLerr(SSL_F_READ_AUTHZ,ERR_R_BUF_LIB);
goto end;
}
if (BIO_read_filename(authz_in,file) <= 0)
{
SSLerr(SSL_F_READ_AUTHZ,ERR_R_SYS_LIB);
goto end;
}
authz = OPENSSL_malloc(authz_limit);
read_length = BIO_read(authz_in, authz, authz_limit);
if (read_length == authz_limit || read_length <= 0)
{
SSLerr(SSL_F_READ_AUTHZ,SSL_R_AUTHZ_DATA_TOO_LARGE);
OPENSSL_free(authz);
goto end;
}
*authz_length = read_length;
ret = authz;
end:
if (authz_in != NULL) BIO_free(authz_in);
return ret;
}
int SSL_CTX_use_authz_file(SSL_CTX *ctx, const char *file)
{
unsigned char *authz = NULL;
size_t authz_length = 0;
int ret;
authz = read_authz(file, &authz_length);
if (authz == NULL)
return 0;
ret = SSL_CTX_use_authz(ctx, authz, authz_length);
/* SSL_CTX_use_authz makes a local copy of the authz. */
OPENSSL_free(authz);
return ret;
}
int SSL_use_authz_file(SSL *ssl, const char *file)
{
unsigned char *authz = NULL;
size_t authz_length = 0;
int ret;
authz = read_authz(file, &authz_length);
if (authz == NULL)
return 0;
ret = SSL_use_authz(ssl, authz, authz_length);
/* SSL_use_authz makes a local copy of the authz. */
OPENSSL_free(authz);
return ret;
}
#endif /* OPENSSL_NO_STDIO */
#endif /* OPENSSL_NO_TLSEXT */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册