1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-23 09:57:40 +03:00

s4:heimdal: import lorikeet-heimdal-200909210500 (commit 290db8d23647a27c39b97c189a0b2ef6ec21ca69)

This commit is contained in:
Andrew Bartlett 2009-09-20 23:18:34 -07:00
parent 1220534716
commit 5bc87c14a1
139 changed files with 4131 additions and 2191 deletions

View File

@ -9,7 +9,8 @@ m4_ifval([$2],[
void * foo(void) { return &$1; }]],[[foo()]])],
[ac_cv_var_$1=yes],[ac_cv_var_$1=no])])
if test "$ac_cv_var_$1" != yes ; then
AC_LINK_IFELSE([AC_LANG_PROGRAM([[extern int $1;
AC_LINK_IFELSE([AC_LANG_PROGRAM([[$2
extern int $1;
int foo(void) { return $1; }]],[[foo()]])],
[ac_cv_var_$1=yes],[ac_cv_var_$1=no])
fi

View File

@ -613,7 +613,7 @@ _kdc_do_digest(krb5_context context,
}
if (strcasecmp(ireq.u.digestRequest.type, "CHAP") == 0) {
MD5_CTX ctx;
EVP_MD_CTX *ctx;
unsigned char md[MD5_DIGEST_LENGTH];
char *mdx;
char id;
@ -642,11 +642,15 @@ _kdc_do_digest(krb5_context context,
if (ret)
goto out;
MD5_Init(&ctx);
MD5_Update(&ctx, &id, 1);
MD5_Update(&ctx, password, strlen(password));
MD5_Update(&ctx, serverNonce.data, serverNonce.length);
MD5_Final(md, &ctx);
ctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
EVP_DigestUpdate(ctx, &id, 1);
EVP_DigestUpdate(ctx, password, strlen(password));
EVP_DigestUpdate(ctx, serverNonce.data, serverNonce.length);
EVP_DigestFinal_ex(ctx, md, NULL);
EVP_MD_CTX_destroy(ctx);
hex_encode(md, sizeof(md), &mdx);
if (mdx == NULL) {
@ -669,7 +673,7 @@ _kdc_do_digest(krb5_context context,
}
} else if (strcasecmp(ireq.u.digestRequest.type, "SASL-DIGEST-MD5") == 0) {
MD5_CTX ctx;
EVP_MD_CTX *ctx;
unsigned char md[MD5_DIGEST_LENGTH];
char *mdx;
char *A1, *A2;
@ -694,49 +698,54 @@ _kdc_do_digest(krb5_context context,
if (ret)
goto failed;
MD5_Init(&ctx);
MD5_Update(&ctx, ireq.u.digestRequest.username,
ctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
EVP_DigestUpdate(ctx, ireq.u.digestRequest.username,
strlen(ireq.u.digestRequest.username));
MD5_Update(&ctx, ":", 1);
MD5_Update(&ctx, *ireq.u.digestRequest.realm,
EVP_DigestUpdate(ctx, ":", 1);
EVP_DigestUpdate(ctx, *ireq.u.digestRequest.realm,
strlen(*ireq.u.digestRequest.realm));
MD5_Update(&ctx, ":", 1);
MD5_Update(&ctx, password, strlen(password));
MD5_Final(md, &ctx);
EVP_DigestUpdate(ctx, ":", 1);
EVP_DigestUpdate(ctx, password, strlen(password));
EVP_DigestFinal_ex(ctx, md, NULL);
MD5_Init(&ctx);
MD5_Update(&ctx, md, sizeof(md));
MD5_Update(&ctx, ":", 1);
MD5_Update(&ctx, ireq.u.digestRequest.serverNonce,
EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
EVP_DigestUpdate(ctx, md, sizeof(md));
EVP_DigestUpdate(ctx, ":", 1);
EVP_DigestUpdate(ctx, ireq.u.digestRequest.serverNonce,
strlen(ireq.u.digestRequest.serverNonce));
MD5_Update(&ctx, ":", 1);
MD5_Update(&ctx, *ireq.u.digestRequest.nonceCount,
EVP_DigestUpdate(ctx, ":", 1);
EVP_DigestUpdate(ctx, *ireq.u.digestRequest.nonceCount,
strlen(*ireq.u.digestRequest.nonceCount));
if (ireq.u.digestRequest.authid) {
MD5_Update(&ctx, ":", 1);
MD5_Update(&ctx, *ireq.u.digestRequest.authid,
EVP_DigestUpdate(ctx, ":", 1);
EVP_DigestUpdate(ctx, *ireq.u.digestRequest.authid,
strlen(*ireq.u.digestRequest.authid));
}
MD5_Final(md, &ctx);
EVP_DigestFinal_ex(ctx, md, NULL);
hex_encode(md, sizeof(md), &A1);
if (A1 == NULL) {
ret = ENOMEM;
krb5_set_error_message(context, ret, "malloc: out of memory");
EVP_MD_CTX_destroy(ctx);
goto failed;
}
MD5_Init(&ctx);
MD5_Update(&ctx, "AUTHENTICATE:", sizeof("AUTHENTICATE:") - 1);
MD5_Update(&ctx, *ireq.u.digestRequest.uri,
EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
EVP_DigestUpdate(ctx,
"AUTHENTICATE:", sizeof("AUTHENTICATE:") - 1);
EVP_DigestUpdate(ctx, *ireq.u.digestRequest.uri,
strlen(*ireq.u.digestRequest.uri));
/* conf|int */
if (strcmp(ireq.u.digestRequest.digest, "clear") != 0) {
static char conf_zeros[] = ":00000000000000000000000000000000";
MD5_Update(&ctx, conf_zeros, sizeof(conf_zeros) - 1);
EVP_DigestUpdate(ctx, conf_zeros, sizeof(conf_zeros) - 1);
}
MD5_Final(md, &ctx);
EVP_DigestFinal_ex(ctx, md, NULL);
hex_encode(md, sizeof(md), &A2);
if (A2 == NULL) {
ret = ENOMEM;
@ -745,24 +754,26 @@ _kdc_do_digest(krb5_context context,
goto failed;
}
MD5_Init(&ctx);
MD5_Update(&ctx, A1, strlen(A2));
MD5_Update(&ctx, ":", 1);
MD5_Update(&ctx, ireq.u.digestRequest.serverNonce,
EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
EVP_DigestUpdate(ctx, A1, strlen(A2));
EVP_DigestUpdate(ctx, ":", 1);
EVP_DigestUpdate(ctx, ireq.u.digestRequest.serverNonce,
strlen(ireq.u.digestRequest.serverNonce));
MD5_Update(&ctx, ":", 1);
MD5_Update(&ctx, *ireq.u.digestRequest.nonceCount,
EVP_DigestUpdate(ctx, ":", 1);
EVP_DigestUpdate(ctx, *ireq.u.digestRequest.nonceCount,
strlen(*ireq.u.digestRequest.nonceCount));
MD5_Update(&ctx, ":", 1);
MD5_Update(&ctx, *ireq.u.digestRequest.clientNonce,
EVP_DigestUpdate(ctx, ":", 1);
EVP_DigestUpdate(ctx, *ireq.u.digestRequest.clientNonce,
strlen(*ireq.u.digestRequest.clientNonce));
MD5_Update(&ctx, ":", 1);
MD5_Update(&ctx, *ireq.u.digestRequest.qop,
EVP_DigestUpdate(ctx, ":", 1);
EVP_DigestUpdate(ctx, *ireq.u.digestRequest.qop,
strlen(*ireq.u.digestRequest.qop));
MD5_Update(&ctx, ":", 1);
MD5_Update(&ctx, A2, strlen(A2));
EVP_DigestUpdate(ctx, ":", 1);
EVP_DigestUpdate(ctx, A2, strlen(A2));
MD5_Final(md, &ctx);
EVP_DigestFinal_ex(ctx, md, NULL);
EVP_MD_CTX_destroy(ctx);
free(A1);
free(A2);
@ -793,7 +804,7 @@ _kdc_do_digest(krb5_context context,
const char *username;
struct ntlm_buf answer;
Key *key = NULL;
SHA_CTX ctx;
EVP_MD_CTX *ctx;
if ((config->digests_allowed & MS_CHAP_V2) == 0) {
kdc_log(context, config, 0, "MS-CHAP-V2 not allowed");
@ -820,8 +831,10 @@ _kdc_do_digest(krb5_context context,
else
username++;
ctx = EVP_MD_CTX_create();
/* ChallangeHash */
SHA1_Init(&ctx);
EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
{
ssize_t ssize;
krb5_data clientNonce;
@ -830,7 +843,9 @@ _kdc_do_digest(krb5_context context,
clientNonce.data = malloc(clientNonce.length);
if (clientNonce.data == NULL) {
ret = ENOMEM;
krb5_set_error_message(context, ret, "malloc: out of memory");
krb5_set_error_message(context, ret,
"malloc: out of memory");
EVP_MD_CTX_destroy(ctx);
goto out;
}
@ -840,14 +855,18 @@ _kdc_do_digest(krb5_context context,
ret = ENOMEM;
krb5_set_error_message(context, ret,
"Failed to decode clientNonce");
EVP_MD_CTX_destroy(ctx);
goto out;
}
SHA1_Update(&ctx, clientNonce.data, ssize);
EVP_DigestUpdate(ctx, clientNonce.data, ssize);
free(clientNonce.data);
}
SHA1_Update(&ctx, serverNonce.data, serverNonce.length);
SHA1_Update(&ctx, username, strlen(username));
SHA1_Final(challange, &ctx);
EVP_DigestUpdate(ctx, serverNonce.data, serverNonce.length);
EVP_DigestUpdate(ctx, username, strlen(username));
EVP_DigestFinal_ex(ctx, challange, NULL);
EVP_MD_CTX_destroy(ctx);
/* NtPasswordHash */
ret = krb5_parse_name(context, username, &clientprincipal);
@ -904,34 +923,39 @@ _kdc_do_digest(krb5_context context,
if (r.u.response.success) {
unsigned char hashhash[MD4_DIGEST_LENGTH];
EVP_MD_CTX *ctx;
ctx = EVP_MD_CTX_create();
/* hashhash */
{
MD4_CTX hctx;
MD4_Init(&hctx);
MD4_Update(&hctx, key->key.keyvalue.data,
key->key.keyvalue.length);
MD4_Final(hashhash, &hctx);
EVP_DigestInit_ex(ctx, EVP_md4(), NULL);
EVP_DigestUpdate(ctx,
key->key.keyvalue.data,
key->key.keyvalue.length);
EVP_DigestFinal_ex(ctx, hashhash, NULL);
}
/* GenerateAuthenticatorResponse */
SHA1_Init(&ctx);
SHA1_Update(&ctx, hashhash, sizeof(hashhash));
SHA1_Update(&ctx, answer.data, answer.length);
SHA1_Update(&ctx, ms_chap_v2_magic1,sizeof(ms_chap_v2_magic1));
SHA1_Final(md, &ctx);
EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
EVP_DigestUpdate(ctx, hashhash, sizeof(hashhash));
EVP_DigestUpdate(ctx, answer.data, answer.length);
EVP_DigestUpdate(ctx, ms_chap_v2_magic1,
sizeof(ms_chap_v2_magic1));
EVP_DigestFinal_ex(ctx, md, NULL);
SHA1_Init(&ctx);
SHA1_Update(&ctx, md, sizeof(md));
SHA1_Update(&ctx, challange, 8);
SHA1_Update(&ctx, ms_chap_v2_magic2, sizeof(ms_chap_v2_magic2));
SHA1_Final(md, &ctx);
EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
EVP_DigestUpdate(ctx, md, sizeof(md));
EVP_DigestUpdate(ctx, challange, 8);
EVP_DigestUpdate(ctx, ms_chap_v2_magic2,
sizeof(ms_chap_v2_magic2));
EVP_DigestFinal_ex(ctx, md, NULL);
r.u.response.rsp = calloc(1, sizeof(*r.u.response.rsp));
if (r.u.response.rsp == NULL) {
free(answer.data);
krb5_clear_error_message(context);
EVP_MD_CTX_destroy(ctx);
ret = ENOMEM;
goto out;
}
@ -940,19 +964,23 @@ _kdc_do_digest(krb5_context context,
if (r.u.response.rsp == NULL) {
free(answer.data);
krb5_clear_error_message(context);
EVP_MD_CTX_destroy(ctx);
ret = ENOMEM;
goto out;
}
/* get_master, rfc 3079 3.4 */
SHA1_Init(&ctx);
SHA1_Update(&ctx, hashhash, 16); /* md4(hash) */
SHA1_Update(&ctx, answer.data, answer.length);
SHA1_Update(&ctx, ms_rfc3079_magic1, sizeof(ms_rfc3079_magic1));
SHA1_Final(md, &ctx);
EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
EVP_DigestUpdate(ctx, hashhash, 16);
EVP_DigestUpdate(ctx, answer.data, answer.length);
EVP_DigestUpdate(ctx, ms_rfc3079_magic1,
sizeof(ms_rfc3079_magic1));
EVP_DigestFinal_ex(ctx, md, NULL);
free(answer.data);
EVP_MD_CTX_destroy(ctx);
r.u.response.session_key =
calloc(1, sizeof(*r.u.response.session_key));
if (r.u.response.session_key == NULL) {
@ -1237,7 +1265,7 @@ _kdc_do_digest(krb5_context context,
if (flags & NTLM_NEG_NTLM2_SESSION) {
unsigned char sessionhash[MD5_DIGEST_LENGTH];
MD5_CTX md5ctx;
EVP_MD_CTX *ctx;
if ((config->digests_allowed & NTLM_V1_SESSION) == 0) {
kdc_log(context, config, 0, "NTLM v1-session not allowed");
@ -1252,11 +1280,17 @@ _kdc_do_digest(krb5_context context,
goto failed;
}
MD5_Init(&md5ctx);
MD5_Update(&md5ctx, challange, sizeof(challange));
MD5_Update(&md5ctx, ireq.u.ntlmRequest.lm.data, 8);
MD5_Final(sessionhash, &md5ctx);
ctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
EVP_DigestUpdate(ctx, challange, sizeof(challange));
EVP_DigestUpdate(ctx, ireq.u.ntlmRequest.lm.data, 8);
EVP_DigestFinal_ex(ctx, sessionhash, NULL);
memcpy(challange, sessionhash, sizeof(challange));
EVP_MD_CTX_destroy(ctx);
} else {
if ((config->digests_allowed & NTLM_V1) == 0) {
kdc_log(context, config, 0, "NTLM v1 not allowed");
@ -1283,18 +1317,23 @@ _kdc_do_digest(krb5_context context,
free(answer.data);
{
MD4_CTX ctx;
EVP_MD_CTX *ctx;
MD4_Init(&ctx);
MD4_Update(&ctx,
key->key.keyvalue.data, key->key.keyvalue.length);
MD4_Final(sessionkey, &ctx);
ctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(ctx, EVP_md4(), NULL);
EVP_DigestUpdate(ctx,
key->key.keyvalue.data,
key->key.keyvalue.length);
EVP_DigestFinal_ex(ctx, sessionkey, NULL);
EVP_MD_CTX_destroy(ctx);
}
}
if (ireq.u.ntlmRequest.sessionkey) {
unsigned char masterkey[MD4_DIGEST_LENGTH];
RC4_KEY rc4;
EVP_CIPHER_CTX rc4;
size_t len;
if ((flags & NTLM_NEG_KEYEX) == 0) {
@ -1314,12 +1353,13 @@ _kdc_do_digest(krb5_context context,
goto failed;
}
RC4_set_key(&rc4, sizeof(sessionkey), sessionkey);
RC4(&rc4, sizeof(masterkey),
ireq.u.ntlmRequest.sessionkey->data,
masterkey);
memset(&rc4, 0, sizeof(rc4));
EVP_CIPHER_CTX_init(&rc4);
EVP_CipherInit_ex(&rc4, EVP_rc4(), NULL, sessionkey, NULL, 1);
EVP_Cipher(&rc4,
masterkey, ireq.u.ntlmRequest.sessionkey->data,
sizeof(masterkey));
EVP_CIPHER_CTX_cleanup(&rc4);
r.u.ntlmResponse.sessionkey =
malloc(sizeof(*r.u.ntlmResponse.sessionkey));

View File

@ -46,7 +46,8 @@ struct Kx509Request;
#include <kdc-private.h>
extern sig_atomic_t exit_flag;
extern size_t max_request;
extern size_t max_request_udp;
extern size_t max_request_tcp;
extern const char *request_log;
extern const char *port_str;
extern krb5_addresses explicit_addresses;

View File

@ -1747,6 +1747,7 @@ _kdc_as_rep(krb5_context context,
config,
server,
setype,
client->entry.principal,
NULL,
NULL,
&et);

View File

@ -106,6 +106,7 @@ _kdc_add_KRB5SignedPath(krb5_context context,
krb5_kdc_configuration *config,
hdb_entry_ex *krbtgt,
krb5_enctype enctype,
krb5_principal client,
krb5_const_principal server,
krb5_principals principals,
EncTicketPart *tkt)
@ -125,8 +126,10 @@ _kdc_add_KRB5SignedPath(krb5_context context,
{
KRB5SignedPathData spd;
spd.encticket = *tkt;
spd.client = client;
spd.authtime = tkt->authtime;
spd.delegated = principals;
spd.method_data = NULL;
ASN1_MALLOC_ENCODE(KRB5SignedPathData, data.data, data.length,
&spd, &size, ret);
@ -153,6 +156,7 @@ _kdc_add_KRB5SignedPath(krb5_context context,
sp.etype = enctype;
sp.delegated = principals;
sp.method_data = NULL;
ret = krb5_create_checksum(context, crypto, KRB5_KU_KRB5SIGNEDPATH, 0,
data.data, data.length, &sp.cksum);
@ -185,6 +189,7 @@ static krb5_error_code
check_KRB5SignedPath(krb5_context context,
krb5_kdc_configuration *config,
hdb_entry_ex *krbtgt,
krb5_principal cp,
EncTicketPart *tkt,
krb5_principals *delegated,
int *signedpath)
@ -200,7 +205,6 @@ check_KRB5SignedPath(krb5_context context,
if (ret == 0) {
KRB5SignedPathData spd;
KRB5SignedPath sp;
AuthorizationData *ad;
size_t size;
ret = decode_KRB5SignedPath(data.data, data.length, &sp, NULL);
@ -208,17 +212,13 @@ check_KRB5SignedPath(krb5_context context,
if (ret)
return ret;
spd.encticket = *tkt;
/* the KRB5SignedPath is the last entry */
ad = spd.encticket.authorization_data;
if (--ad->len == 0)
spd.encticket.authorization_data = NULL;
spd.client = cp;
spd.authtime = tkt->authtime;
spd.delegated = sp.delegated;
spd.method_data = sp.method_data;
ASN1_MALLOC_ENCODE(KRB5SignedPathData, data.data, data.length,
&spd, &size, ret);
ad->len++;
spd.encticket.authorization_data = ad;
if (ret) {
free_KRB5SignedPath(&sp);
return ret;
@ -244,7 +244,9 @@ check_KRB5SignedPath(krb5_context context,
free(data.data);
if (ret) {
free_KRB5SignedPath(&sp);
return ret;
kdc_log(context, config, 5,
"KRB5SignedPath not signed correctly, not marking as signed");
return 0;
}
if (delegated && sp.delegated) {
@ -884,6 +886,7 @@ tgs_make_reply(krb5_context context,
config,
krbtgt,
krbtgt_etype,
client_principal,
NULL,
spp,
&et);
@ -1663,6 +1666,7 @@ server_lookup:
ret = check_KRB5SignedPath(context,
config,
krbtgt,
cp,
tgt,
&spp,
&signedpath);
@ -1855,6 +1859,7 @@ server_lookup:
ret = check_KRB5SignedPath(context,
config,
krbtgt,
cp,
&adtkt,
NULL,
&ad_signedpath);

View File

@ -645,8 +645,10 @@ PA-S4U2Self ::= SEQUENCE {
-- never encoded on the wire, just used to checksum over
KRB5SignedPathData ::= SEQUENCE {
encticket[0] EncTicketPart,
delegated[1] Principals OPTIONAL
client[0] Principal OPTIONAL,
authtime[1] KerberosTime,
delegated[2] Principals OPTIONAL,
method_data[3] METHOD-DATA OPTIONAL
}
KRB5SignedPath ::= SEQUENCE {
@ -655,7 +657,8 @@ KRB5SignedPath ::= SEQUENCE {
etype[0] ENCTYPE,
cksum[1] Checksum,
-- srvs delegated though
delegated[2] Principals OPTIONAL
delegated[2] Principals OPTIONAL,
method_data[3] METHOD-DATA OPTIONAL
}
PA-ClientCanonicalizedNames ::= SEQUENCE{

View File

@ -356,10 +356,15 @@ _gss_import_cred_t(OM_uint32 * minor_status,
#define GMI_VERSION 2
/* gm_flags */
#define GM_USE_MG_CRED 1 /* uses mech glue credentials */
typedef struct gssapi_mech_interface_desc {
unsigned gm_version;
const char *gm_name;
gss_OID_desc gm_mech_oid;
unsigned gm_flags;
_gss_acquire_cred_t *gm_acquire_cred;
_gss_release_cred_t *gm_release_cred;
_gss_init_sec_context_t *gm_init_sec_context;

View File

@ -74,32 +74,36 @@ hash_input_chan_bindings (const gss_channel_bindings_t b,
u_char *p)
{
u_char num[4];
MD5_CTX md5;
EVP_MD_CTX *ctx;
ctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
MD5_Init(&md5);
_gsskrb5_encode_om_uint32 (b->initiator_addrtype, num);
MD5_Update (&md5, num, sizeof(num));
EVP_DigestUpdate(ctx, num, sizeof(num));
_gsskrb5_encode_om_uint32 (b->initiator_address.length, num);
MD5_Update (&md5, num, sizeof(num));
EVP_DigestUpdate(ctx, num, sizeof(num));
if (b->initiator_address.length)
MD5_Update (&md5,
b->initiator_address.value,
b->initiator_address.length);
EVP_DigestUpdate(ctx,
b->initiator_address.value,
b->initiator_address.length);
_gsskrb5_encode_om_uint32 (b->acceptor_addrtype, num);
MD5_Update (&md5, num, sizeof(num));
EVP_DigestUpdate(ctx, num, sizeof(num));
_gsskrb5_encode_om_uint32 (b->acceptor_address.length, num);
MD5_Update (&md5, num, sizeof(num));
EVP_DigestUpdate(ctx, num, sizeof(num));
if (b->acceptor_address.length)
MD5_Update (&md5,
b->acceptor_address.value,
b->acceptor_address.length);
EVP_DigestUpdate(ctx,
b->acceptor_address.value,
b->acceptor_address.length);
_gsskrb5_encode_om_uint32 (b->application_data.length, num);
MD5_Update (&md5, num, sizeof(num));
EVP_DigestUpdate(ctx, num, sizeof(num));
if (b->application_data.length)
MD5_Update (&md5,
b->application_data.value,
b->application_data.length);
MD5_Final (p, &md5);
EVP_DigestUpdate(ctx,
b->application_data.value,
b->application_data.length);
EVP_DigestFinal_ex(ctx, p, NULL);
EVP_MD_CTX_destroy(ctx);
return 0;
}
@ -204,7 +208,7 @@ _gsskrb5_verify_8003_checksum(
*minor_status = 0;
return GSS_S_BAD_BINDINGS;
}
if(memcmp(hash, p, sizeof(hash)) != 0) {
if(ct_memcmp(hash, p, sizeof(hash)) != 0) {
*minor_status = 0;
return GSS_S_BAD_BINDINGS;
}

View File

@ -35,7 +35,7 @@
#include <roken.h>
OM_uint32 GSSAPI_LIB_FUNCTION
OM_uint32
_gk_wrap_iov(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
@ -57,7 +57,7 @@ _gk_wrap_iov(OM_uint32 * minor_status,
return GSS_S_FAILURE;
}
OM_uint32 GSSAPI_LIB_FUNCTION
OM_uint32
_gk_unwrap_iov(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
int *conf_state,
@ -77,7 +77,7 @@ _gk_unwrap_iov(OM_uint32 *minor_status,
return GSS_S_FAILURE;
}
OM_uint32 GSSAPI_LIB_FUNCTION
OM_uint32
_gk_wrap_iov_length(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,

View File

@ -173,7 +173,7 @@ _gssapi_get_mic_arcfour(OM_uint32 * minor_status,
int32_t seq_number;
size_t len, total_len;
u_char k6_data[16], *p0, *p;
RC4_KEY rc4_key;
EVP_CIPHER_CTX rc4_key;
_gsskrb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM);
@ -235,10 +235,11 @@ _gssapi_get_mic_arcfour(OM_uint32 * minor_status,
memset (p + 4, (context_handle->more_flags & LOCAL) ? 0 : 0xff, 4);
RC4_set_key (&rc4_key, sizeof(k6_data), k6_data);
RC4 (&rc4_key, 8, p, p);
memset(&rc4_key, 0, sizeof(rc4_key));
EVP_CIPHER_CTX_init(&rc4_key);
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
EVP_Cipher(&rc4_key, p, p, 8);
EVP_CIPHER_CTX_cleanup(&rc4_key);
memset(k6_data, 0, sizeof(k6_data));
*minor_status = 0;
@ -300,19 +301,20 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status,
return GSS_S_FAILURE;
}
cmp = memcmp(cksum_data, p + 8, 8);
cmp = ct_memcmp(cksum_data, p + 8, 8);
if (cmp) {
*minor_status = 0;
return GSS_S_BAD_MIC;
}
{
RC4_KEY rc4_key;
EVP_CIPHER_CTX rc4_key;
RC4_set_key (&rc4_key, sizeof(k6_data), (void*)k6_data);
RC4 (&rc4_key, 8, p, SND_SEQ);
memset(&rc4_key, 0, sizeof(rc4_key));
EVP_CIPHER_CTX_init(&rc4_key);
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, (void *)k6_data, NULL, 0);
EVP_Cipher(&rc4_key, SND_SEQ, p, 8);
EVP_CIPHER_CTX_cleanup(&rc4_key);
memset(k6_data, 0, sizeof(k6_data));
}
@ -459,12 +461,12 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status,
if(conf_req_flag) {
RC4_KEY rc4_key;
RC4_set_key (&rc4_key, sizeof(k6_data), (void *)k6_data);
/* XXX ? */
RC4 (&rc4_key, 8 + datalen, p0 + 24, p0 + 24); /* Confounder + data */
memset(&rc4_key, 0, sizeof(rc4_key));
EVP_CIPHER_CTX rc4_key;
EVP_CIPHER_CTX_init(&rc4_key);
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
EVP_Cipher(&rc4_key, p0 + 24, p0 + 24, 8 + datalen);
EVP_CIPHER_CTX_cleanup(&rc4_key);
}
memset(k6_data, 0, sizeof(k6_data));
@ -478,11 +480,12 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status,
}
{
RC4_KEY rc4_key;
EVP_CIPHER_CTX rc4_key;
RC4_set_key (&rc4_key, sizeof(k6_data), k6_data);
RC4 (&rc4_key, 8, p0 + 8, p0 + 8); /* SND_SEQ */
memset(&rc4_key, 0, sizeof(rc4_key));
EVP_CIPHER_CTX_init(&rc4_key);
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
EVP_Cipher(&rc4_key, p0 + 8, p0 + 8 /* SND_SEQ */, 8);
EVP_CIPHER_CTX_cleanup(&rc4_key);
memset(k6_data, 0, sizeof(k6_data));
}
@ -577,11 +580,12 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
}
{
RC4_KEY rc4_key;
EVP_CIPHER_CTX rc4_key;
RC4_set_key (&rc4_key, sizeof(k6_data), k6_data);
RC4 (&rc4_key, 8, p0 + 8, SND_SEQ); /* SND_SEQ */
memset(&rc4_key, 0, sizeof(rc4_key));
EVP_CIPHER_CTX_init(&rc4_key);
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
EVP_Cipher(&rc4_key, SND_SEQ, p0 + 8, 8);
EVP_CIPHER_CTX_cleanup(&rc4_key);
memset(k6_data, 0, sizeof(k6_data));
}
@ -624,13 +628,13 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
output_message_buffer->length = datalen;
if(conf_flag) {
RC4_KEY rc4_key;
RC4_set_key (&rc4_key, sizeof(k6_data), k6_data);
RC4 (&rc4_key, 8, p0 + 24, Confounder); /* Confounder */
RC4 (&rc4_key, datalen, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE,
output_message_buffer->value);
memset(&rc4_key, 0, sizeof(rc4_key));
EVP_CIPHER_CTX rc4_key;
EVP_CIPHER_CTX_init(&rc4_key);
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
EVP_Cipher(&rc4_key, Confounder, p0 + 24, 8);
EVP_Cipher(&rc4_key, output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen);
EVP_CIPHER_CTX_cleanup(&rc4_key);
} else {
memcpy(Confounder, p0 + 24, 8); /* Confounder */
memcpy(output_message_buffer->value,
@ -662,7 +666,7 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
return GSS_S_FAILURE;
}
cmp = memcmp(cksum_data, p0 + 16, 8); /* SGN_CKSUM */
cmp = ct_memcmp(cksum_data, p0 + 16, 8); /* SGN_CKSUM */
if (cmp) {
_gsskrb5_release_buffer(minor_status, output_message_buffer);
*minor_status = 0;

View File

@ -213,8 +213,8 @@ _gk_find_buffer(gss_iov_buffer_desc *iov, int iov_count, OM_uint32 type)
return NULL;
}
static OM_uint32
allocate_buffer(OM_uint32 *minor_status, gss_iov_buffer_desc *buffer, size_t size)
OM_uint32
_gk_allocate_buffer(OM_uint32 *minor_status, gss_iov_buffer_desc *buffer, size_t size)
{
if (buffer->type & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED) {
if (buffer->buffer.length == size)
@ -234,6 +234,43 @@ allocate_buffer(OM_uint32 *minor_status, gss_iov_buffer_desc *buffer, size_t siz
}
OM_uint32
_gk_verify_buffers(OM_uint32 *minor_status,
const gsskrb5_ctx ctx,
const gss_iov_buffer_desc *header,
const gss_iov_buffer_desc *padding,
const gss_iov_buffer_desc *trailer)
{
if (header == NULL) {
*minor_status = EINVAL;
return GSS_S_FAILURE;
}
if (IS_DCE_STYLE(ctx)) {
/*
* In DCE style mode we reject having a padding or trailer buffer
*/
if (padding) {
*minor_status = EINVAL;
return GSS_S_FAILURE;
}
if (trailer) {
*minor_status = EINVAL;
return GSS_S_FAILURE;
}
} else {
/*
* In non-DCE style mode we require having a padding buffer
*/
if (padding == NULL) {
*minor_status = EINVAL;
return GSS_S_FAILURE;
}
}
*minor_status = 0;
return GSS_S_COMPLETE;
}
OM_uint32
_gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
@ -248,44 +285,99 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
gss_iov_buffer_desc *header, *trailer, *padding;
size_t gsshsize, k5hsize;
size_t gsstsize, k5tsize;
size_t i, padlength, rrc = 0, ec = 0;
size_t i, rrc = 0, ec = 0;
gss_cfx_wrap_token token;
krb5_error_code ret;
int32_t seq_number;
unsigned usage;
krb5_crypto_iov *data = NULL;
int paddingoffset = 0;
header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
if (header == NULL) {
*minor_status = EINVAL;
return GSS_S_FAILURE;
}
krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_PADDING, &padlength);
padding = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING);
if (padlength != 0 && padding == NULL) {
*minor_status = EINVAL;
return GSS_S_FAILURE;
if (padding != NULL) {
padding->buffer.length = 0;
}
trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
major_status = _gk_verify_buffers(minor_status, ctx, header, padding, trailer);
if (major_status != GSS_S_COMPLETE) {
return major_status;
}
if (conf_req_flag) {
ec = padlength;
size_t k5psize = 0;
size_t k5pbase = 0;
size_t k5bsize = 0;
size_t size = 0;
krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER, &k5tsize);
krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER, &k5hsize);
for (i = 0; i < iov_count; i++) {
switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
case GSS_IOV_BUFFER_TYPE_DATA:
size += iov[i].buffer.length;
break;
default:
break;
}
}
gsshsize = k5hsize + sizeof(*token);
gsstsize = k5tsize + sizeof(*token); /* encrypted token stored in trailer */
size += sizeof(gss_cfx_wrap_token_desc);
*minor_status = krb5_crypto_length(context, ctx->crypto,
KRB5_CRYPTO_TYPE_HEADER,
&k5hsize);
if (*minor_status)
return GSS_S_FAILURE;
*minor_status = krb5_crypto_length(context, ctx->crypto,
KRB5_CRYPTO_TYPE_TRAILER,
&k5tsize);
if (*minor_status)
return GSS_S_FAILURE;
*minor_status = krb5_crypto_length(context, ctx->crypto,
KRB5_CRYPTO_TYPE_PADDING,
&k5pbase);
if (*minor_status)
return GSS_S_FAILURE;
if (k5pbase > 1) {
k5psize = k5pbase - (size % k5pbase);
} else {
k5psize = 0;
}
if (k5psize == 0 && IS_DCE_STYLE(ctx)) {
*minor_status = krb5_crypto_getblocksize(context, ctx->crypto,
&k5bsize);
if (*minor_status)
return GSS_S_FAILURE;
ec = k5bsize;
} else {
ec = k5psize;
}
gsshsize = sizeof(gss_cfx_wrap_token_desc) + k5hsize;
gsstsize = sizeof(gss_cfx_wrap_token_desc) + ec + k5tsize;
} else {
if (IS_DCE_STYLE(ctx)) {
*minor_status = EINVAL;
return GSS_S_FAILURE;
}
krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_CHECKSUM, &k5tsize);
k5hsize = 0;
*minor_status = krb5_crypto_length(context, ctx->crypto,
KRB5_CRYPTO_TYPE_CHECKSUM,
&k5tsize);
if (*minor_status)
return GSS_S_FAILURE;
gsshsize = sizeof(*token);
gsshsize = sizeof(gss_cfx_wrap_token_desc);
gsstsize = k5tsize;
}
@ -294,19 +386,13 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
*/
if (trailer == NULL) {
/* conf_req_flag=0 doesn't support DCE_STYLE */
if (conf_req_flag == 0) {
*minor_status = EINVAL;
major_status = GSS_S_FAILURE;
goto failure;
}
rrc = gsstsize;
if (IS_DCE_STYLE(ctx))
rrc -= ec;
gsshsize += gsstsize;
gsstsize = 0;
} else if (GSS_IOV_BUFFER_FLAGS(trailer->type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE) {
major_status = allocate_buffer(minor_status, trailer, gsstsize);
major_status = _gk_allocate_buffer(minor_status, trailer, gsstsize);
if (major_status)
goto failure;
} else if (trailer->buffer.length < gsstsize) {
@ -321,7 +407,7 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
*/
if (GSS_IOV_BUFFER_FLAGS(header->type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE) {
major_status = allocate_buffer(minor_status, header, gsshsize);
major_status = _gk_allocate_buffer(minor_status, header, gsshsize);
if (major_status != GSS_S_COMPLETE)
goto failure;
} else if (header->buffer.length < gsshsize) {
@ -352,8 +438,8 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
* used to encode the size (in bytes) of the random filler.
*/
token->Flags |= CFXSealed;
token->EC[0] = (padlength >> 8) & 0xFF;
token->EC[1] = (padlength >> 0) & 0xFF;
token->EC[0] = (ec >> 8) & 0xFF;
token->EC[1] = (ec >> 0) & 0xFF;
} else {
/*
@ -404,15 +490,15 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
/*
plain packet:
{"header" | encrypt(plaintext-data | padding | E"header")}
{"header" | encrypt(plaintext-data | ec-padding | E"header")}
Expanded, this is with with RRC = 0:
{"header" | krb5-header | plaintext-data | padding | E"header" | krb5-trailer }
{"header" | krb5-header | plaintext-data | ec-padding | E"header" | krb5-trailer }
In DCE-RPC mode == no trailer: RRC = gss "trailer" == length(padding | E"header" | krb5-trailer)
In DCE-RPC mode == no trailer: RRC = gss "trailer" == length(ec-padding | E"header" | krb5-trailer)
{"header" | padding | E"header" | krb5-trailer | krb5-header | plaintext-data }
{"header" | ec-padding | E"header" | krb5-trailer | krb5-header | plaintext-data }
*/
i = 0;
@ -425,10 +511,6 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
case GSS_IOV_BUFFER_TYPE_DATA:
data[i].flags = KRB5_CRYPTO_TYPE_DATA;
break;
case GSS_IOV_BUFFER_TYPE_PADDING:
data[i].flags = KRB5_CRYPTO_TYPE_PADDING;
paddingoffset = i;
break;
case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
break;
@ -446,8 +528,6 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
* ciphertext.
*/
/* XXX KRB5_CRYPTO_TYPE_PADDING */
/* encrypted CFX header in trailer (or after the header if in
DCE mode). Copy in header into E"header"
*/
@ -455,15 +535,16 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
if (trailer)
data[i].data.data = trailer->buffer.value;
else
data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize - k5tsize - sizeof(*token);
data[i].data.data = ((uint8_t *)header->buffer.value) + sizeof(*token);
data[i].data.length = sizeof(*token);
memcpy(data[i].data.data, token, sizeof(*token));
data[i].data.length = ec + sizeof(*token);
memset(data[i].data.data, 0xFF, ec);
memcpy(((uint8_t *)data[i].data.data) + ec, token, sizeof(*token));
i++;
/* Kerberos trailer comes after the gss trailer */
data[i].flags = KRB5_CRYPTO_TYPE_TRAILER;
data[i].data.data = ((uint8_t *)data[i-1].data.data) + sizeof(*token);
data[i].data.data = ((uint8_t *)data[i-1].data.data) + ec + sizeof(*token);
data[i].data.length = k5tsize;
i++;
@ -479,9 +560,6 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
token->RRC[1] = (rrc >> 0) & 0xFF;
}
if (paddingoffset)
padding->buffer.length = data[paddingoffset].data.length;
} else {
/*
plain packet:
@ -495,7 +573,6 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
for (i = 0; i < iov_count; i++) {
switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
case GSS_IOV_BUFFER_TYPE_DATA:
case GSS_IOV_BUFFER_TYPE_PADDING:
data[i].flags = KRB5_CRYPTO_TYPE_DATA;
break;
case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
@ -511,12 +588,17 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
data[i].flags = KRB5_CRYPTO_TYPE_DATA;
data[i].data.data = header->buffer.value;
data[i].data.length = header->buffer.length;
data[i].data.length = sizeof(gss_cfx_wrap_token_desc);
i++;
data[i].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
data[i].data.data = trailer->buffer.value;
data[i].data.length = trailer->buffer.length;
if (trailer) {
data[i].data.data = trailer->buffer.value;
} else {
data[i].data.data = (uint8_t *)header->buffer.value +
sizeof(gss_cfx_wrap_token_desc);
}
data[i].data.length = k5tsize;
i++;
ret = krb5_create_checksum_iov(context, ctx->crypto, usage, data, i, NULL);
@ -526,8 +608,13 @@ _gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
goto failure;
}
token->EC[0] = (trailer->buffer.length >> 8) & 0xFF;
token->EC[1] = (trailer->buffer.length >> 0) & 0xFF;
if (rrc) {
token->RRC[0] = (rrc >> 8) & 0xFF;
token->RRC[1] = (rrc >> 0) & 0xFF;
}
token->EC[0] = (k5tsize >> 8) & 0xFF;
token->EC[1] = (k5tsize >> 0) & 0xFF;
}
if (conf_state != NULL)
@ -606,7 +693,7 @@ unrotate_iov(OM_uint32 *minor_status, size_t rrc, gss_iov_buffer_desc *iov, int
GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING ||
GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER)
{
memcpy(q, iov[i].buffer.value, MIN(iov[i].buffer.length, skip));
memcpy(q, iov[i].buffer.value, min(iov[i].buffer.length, skip));
if (iov[i].buffer.length > skip)
break;
skip -= iov[i].buffer.length;
@ -627,7 +714,7 @@ _gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
int iov_count)
{
OM_uint32 seq_number_lo, seq_number_hi, major_status, junk;
gss_iov_buffer_desc *header, *trailer;
gss_iov_buffer_desc *header, *trailer, *padding;
gss_cfx_wrap_token token, ttoken;
u_char token_flags;
krb5_error_code ret;
@ -647,8 +734,19 @@ _gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
if (header->buffer.length < sizeof(*token)) /* we check exact below */
return GSS_S_DEFECTIVE_TOKEN;
padding = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING);
if (padding != NULL && padding->buffer.length != 0) {
*minor_status = EINVAL;
return GSS_S_FAILURE;
}
trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
major_status = _gk_verify_buffers(minor_status, ctx, header, padding, trailer);
if (major_status != GSS_S_COMPLETE) {
return major_status;
}
token = (gss_cfx_wrap_token)header->buffer.value;
if (token->TOK_ID[0] != 0x05 || token->TOK_ID[1] != 0x04)
@ -730,14 +828,16 @@ _gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
size_t gsstsize = k5tsize + sizeof(*token);
size_t gsshsize = k5hsize + sizeof(*token);
if (IS_DCE_STYLE(ctx))
gsstsize += ec;
gsshsize += gsstsize;
if (rrc != gsstsize) {
major_status = GSS_S_DEFECTIVE_TOKEN;
goto failure;
}
if (IS_DCE_STYLE(ctx))
gsstsize += ec;
gsshsize += gsstsize;
if (header->buffer.length != gsshsize) {
major_status = GSS_S_DEFECTIVE_TOKEN;
goto failure;
@ -764,7 +864,6 @@ _gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
for (j = 0; j < iov_count; i++, j++) {
switch (GSS_IOV_BUFFER_TYPE(iov[j].type)) {
case GSS_IOV_BUFFER_TYPE_DATA:
case GSS_IOV_BUFFER_TYPE_PADDING:
data[i].flags = KRB5_CRYPTO_TYPE_DATA;
break;
case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
@ -782,17 +881,20 @@ _gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
DCE mode). Copy in header into E"header"
*/
data[i].flags = KRB5_CRYPTO_TYPE_DATA;
if (trailer)
if (trailer) {
data[i].data.data = trailer->buffer.value;
else
data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize - k5tsize - sizeof(*token);
data[i].data.length = sizeof(*token);
ttoken = (gss_cfx_wrap_token)data[i].data.data;
} else {
data[i].data.data = ((uint8_t *)header->buffer.value) +
header->buffer.length - k5hsize - k5tsize - ec- sizeof(*token);
}
data[i].data.length = ec + sizeof(*token);
ttoken = (gss_cfx_wrap_token)(((uint8_t *)data[i].data.data) + ec);
i++;
/* Kerberos trailer comes after the gss trailer */
data[i].flags = KRB5_CRYPTO_TYPE_TRAILER;
data[i].data.data = ((uint8_t *)data[i-1].data.data) + sizeof(*token);
data[i].data.data = ((uint8_t *)data[i-1].data.data) + ec + sizeof(*token);
data[i].data.length = k5tsize;
i++;
@ -807,34 +909,42 @@ _gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
ttoken->RRC[1] = token->RRC[1];
/* Check the integrity of the header */
if (memcmp(ttoken, token, sizeof(*token)) != 0) {
if (ct_memcmp(ttoken, token, sizeof(*token)) != 0) {
major_status = GSS_S_BAD_MIC;
goto failure;
}
} else {
/* Check RRC */
if (rrc != 0) {
*minor_status = EINVAL;
major_status = GSS_S_FAILURE;
goto failure;
}
size_t gsstsize = ec;
size_t gsshsize = sizeof(*token);
if (trailer == NULL) {
/* Check RRC */
if (rrc != gsstsize) {
*minor_status = EINVAL;
major_status = GSS_S_FAILURE;
goto failure;
}
gsshsize += gsstsize;
gsstsize = 0;
} else if (trailer->buffer.length != gsstsize) {
major_status = GSS_S_DEFECTIVE_TOKEN;
goto failure;
} else if (rrc != 0) {
/* Check RRC */
*minor_status = EINVAL;
major_status = GSS_S_FAILURE;
goto failure;
}
if (trailer->buffer.length != ec) {
*minor_status = EINVAL;
major_status = GSS_S_FAILURE;
if (header->buffer.length != gsshsize) {
major_status = GSS_S_DEFECTIVE_TOKEN;
goto failure;
}
for (i = 0; i < iov_count; i++) {
switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
case GSS_IOV_BUFFER_TYPE_DATA:
case GSS_IOV_BUFFER_TYPE_PADDING:
data[i].flags = KRB5_CRYPTO_TYPE_DATA;
break;
case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
@ -850,12 +960,17 @@ _gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
data[i].flags = KRB5_CRYPTO_TYPE_DATA;
data[i].data.data = header->buffer.value;
data[i].data.length = header->buffer.length;
data[i].data.length = sizeof(*token);
i++;
data[i].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
data[i].data.data = trailer->buffer.value;
data[i].data.length = trailer->buffer.length;
if (trailer) {
data[i].data.data = trailer->buffer.value;
} else {
data[i].data.data = (uint8_t *)header->buffer.value +
sizeof(*token);
}
data[i].data.length = ec;
i++;
token = (gss_cfx_wrap_token)header->buffer.value;
@ -900,9 +1015,16 @@ _gssapi_wrap_iov_length_cfx(OM_uint32 *minor_status,
gss_iov_buffer_desc *iov,
int iov_count)
{
OM_uint32 major_status;
size_t size;
int i;
size_t *padding = NULL;
gss_iov_buffer_desc *header = NULL;
gss_iov_buffer_desc *padding = NULL;
gss_iov_buffer_desc *trailer = NULL;
size_t gsshsize = 0;
size_t gsstsize = 0;
size_t k5hsize = 0;
size_t k5tsize = 0;
GSSAPI_KRB5_INIT (&context);
*minor_status = 0;
@ -915,21 +1037,25 @@ _gssapi_wrap_iov_length_cfx(OM_uint32 *minor_status,
size += iov[i].buffer.length;
break;
case GSS_IOV_BUFFER_TYPE_HEADER:
*minor_status = krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER, &iov[i].buffer.length);
if (*minor_status)
if (header != NULL) {
*minor_status = 0;
return GSS_S_FAILURE;
}
header = &iov[i];
break;
case GSS_IOV_BUFFER_TYPE_TRAILER:
*minor_status = krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER, &iov[i].buffer.length);
if (*minor_status)
if (trailer != NULL) {
*minor_status = 0;
return GSS_S_FAILURE;
}
trailer = &iov[i];
break;
case GSS_IOV_BUFFER_TYPE_PADDING:
if (padding != NULL) {
*minor_status = 0;
return GSS_S_FAILURE;
}
padding = &iov[i].buffer.length;
padding = &iov[i];
break;
case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
break;
@ -938,15 +1064,83 @@ _gssapi_wrap_iov_length_cfx(OM_uint32 *minor_status,
return GSS_S_FAILURE;
}
}
major_status = _gk_verify_buffers(minor_status, ctx, header, padding, trailer);
if (major_status != GSS_S_COMPLETE) {
return major_status;
}
if (conf_req_flag) {
size_t k5psize = 0;
size_t k5pbase = 0;
size_t k5bsize = 0;
size_t ec = 0;
size += sizeof(gss_cfx_wrap_token_desc);
*minor_status = krb5_crypto_length(context, ctx->crypto,
KRB5_CRYPTO_TYPE_HEADER,
&k5hsize);
if (*minor_status)
return GSS_S_FAILURE;
*minor_status = krb5_crypto_length(context, ctx->crypto,
KRB5_CRYPTO_TYPE_TRAILER,
&k5tsize);
if (*minor_status)
return GSS_S_FAILURE;
*minor_status = krb5_crypto_length(context, ctx->crypto,
KRB5_CRYPTO_TYPE_PADDING,
&k5pbase);
if (*minor_status)
return GSS_S_FAILURE;
if (k5pbase > 1) {
k5psize = k5pbase - (size % k5pbase);
} else {
k5psize = 0;
}
if (k5psize == 0 && IS_DCE_STYLE(ctx)) {
*minor_status = krb5_crypto_getblocksize(context, ctx->crypto,
&k5bsize);
if (*minor_status)
return GSS_S_FAILURE;
ec = k5bsize;
} else {
ec = k5psize;
}
gsshsize = sizeof(gss_cfx_wrap_token_desc) + k5hsize;
gsstsize = sizeof(gss_cfx_wrap_token_desc) + ec + k5tsize;
} else {
*minor_status = krb5_crypto_length(context, ctx->crypto,
KRB5_CRYPTO_TYPE_CHECKSUM,
&k5tsize);
if (*minor_status)
return GSS_S_FAILURE;
gsshsize = sizeof(gss_cfx_wrap_token_desc);
gsstsize = k5tsize;
}
if (trailer != NULL) {
trailer->buffer.length = gsstsize;
} else {
gsshsize += gsstsize;
}
header->buffer.length = gsshsize;
if (padding) {
size_t pad;
krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_PADDING, &pad);
if (pad > 1) {
*padding = pad - (size % pad);
if (*padding == pad)
*padding = 0;
} else
*padding = 0;
/* padding is done via EC and is contained in the header or trailer */
padding->buffer.length = 0;
}
if (conf_state) {
*conf_state = conf_req_flag;
}
return GSS_S_COMPLETE;
@ -1294,7 +1488,7 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
((gss_cfx_wrap_token)p)->RRC[1] = token->RRC[1];
/* Check the integrity of the header */
if (memcmp(p, token, sizeof(*token)) != 0) {
if (ct_memcmp(p, token, sizeof(*token)) != 0) {
krb5_data_free(&data);
return GSS_S_BAD_MIC;
}
@ -1496,7 +1690,7 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
return GSS_S_DEFECTIVE_TOKEN;
}
if (memcmp(token->Filler, "\xff\xff\xff\xff\xff", 5) != 0) {
if (ct_memcmp(token->Filler, "\xff\xff\xff\xff\xff", 5) != 0) {
return GSS_S_DEFECTIVE_TOKEN;
}

View File

@ -250,5 +250,6 @@ _gsskrb5_import_cred(OM_uint32 * minor_status,
handle->cred_flags = flags;
*cred_handle = (gss_cred_id_t)handle;
return GSS_S_COMPLETE;
}

View File

@ -80,9 +80,9 @@ _gssapi_verify_mech_header(u_char **str,
if (mech_len != mech->length)
return GSS_S_BAD_MECH;
if (memcmp(p,
mech->elements,
mech->length) != 0)
if (ct_memcmp(p,
mech->elements,
mech->length) != 0)
return GSS_S_BAD_MECH;
p += mech_len;
*str = rk_UNCONST(p);
@ -108,7 +108,7 @@ _gsskrb5_verify_header(u_char **str,
if (len < 2)
return GSS_S_DEFECTIVE_TOKEN;
if (memcmp (*str, type, 2) != 0)
if (ct_memcmp (*str, type, 2) != 0)
return GSS_S_DEFECTIVE_TOKEN;
*str += 2;

View File

@ -434,6 +434,7 @@ static gssapi_mech_interface_desc krb5_mech = {
GMI_VERSION,
"kerberos 5",
{9, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" },
0,
_gsskrb5_acquire_cred,
_gsskrb5_release_cred,
_gsskrb5_init_sec_context,

View File

@ -33,6 +33,8 @@
#include "gsskrb5_locl.h"
#ifdef HEIM_WEAK_CRYPTO
static OM_uint32
mic_des
(OM_uint32 * minor_status,
@ -45,9 +47,10 @@ mic_des
)
{
u_char *p;
MD5_CTX md5;
EVP_MD_CTX *md5;
u_char hash[16];
DES_key_schedule schedule;
EVP_CIPHER_CTX des_ctx;
DES_cblock deskey;
DES_cblock zero;
int32_t seq_number;
@ -79,10 +82,12 @@ mic_des
p += 16;
/* checksum */
MD5_Init (&md5);
MD5_Update (&md5, p - 24, 8);
MD5_Update (&md5, message_buffer->value, message_buffer->length);
MD5_Final (hash, &md5);
md5 = EVP_MD_CTX_create();
EVP_DigestInit_ex(md5, EVP_md5(), NULL);
EVP_DigestUpdate(md5, p - 24, 8);
EVP_DigestUpdate(md5, message_buffer->value, message_buffer->length);
EVP_DigestFinal_ex(md5, hash, NULL);
EVP_MD_CTX_destroy(md5);
memset (&zero, 0, sizeof(zero));
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
@ -106,9 +111,10 @@ mic_des
(ctx->more_flags & LOCAL) ? 0 : 0xFF,
4);
DES_set_key_unchecked (&deskey, &schedule);
DES_cbc_encrypt ((void *)p, (void *)p, 8,
&schedule, (DES_cblock *)(p + 8), DES_ENCRYPT);
EVP_CIPHER_CTX_init(&des_ctx);
EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, p + 8, 1);
EVP_Cipher(&des_ctx, p, p, 8);
EVP_CIPHER_CTX_cleanup(&des_ctx);
krb5_auth_con_setlocalseqnumber (context,
ctx->auth_context,
@ -121,6 +127,7 @@ mic_des
*minor_status = 0;
return GSS_S_COMPLETE;
}
#endif
static OM_uint32
mic_des3
@ -297,8 +304,12 @@ OM_uint32 _gsskrb5_get_mic
switch (keytype) {
case KEYTYPE_DES :
#ifdef HEIM_WEAK_CRYPTO
ret = mic_des (minor_status, ctx, context, qop_req,
message_buffer, message_token, key);
#else
ret = GSS_S_FAILURE;
#endif
break;
case KEYTYPE_DES3 :
ret = mic_des3 (minor_status, ctx, context, qop_req,

View File

@ -111,11 +111,6 @@ typedef struct Principal *gsskrb5_name;
extern krb5_keytab _gsskrb5_keytab;
extern HEIMDAL_MUTEX gssapi_keytab_mutex;
struct gssapi_thr_context {
HEIMDAL_MUTEX mutex;
char *error_string;
};
/*
* Prototypes
*/

View File

@ -175,20 +175,21 @@ gsskrb5_get_creds(
const gss_name_t target_name,
int use_dns,
OM_uint32 time_req,
OM_uint32 * time_rec,
krb5_creds ** cred)
OM_uint32 * time_rec)
{
OM_uint32 ret;
krb5_error_code kret;
krb5_creds this_cred;
OM_uint32 lifetime_rec;
*cred = NULL;
if (ctx->target) {
krb5_free_principal(context, ctx->target);
ctx->target = NULL;
}
if (ctx->kcred) {
krb5_free_creds(context, ctx->kcred);
ctx->kcred = NULL;
}
ret = _gsskrb5_canon_name(minor_status, context, use_dns,
ctx->source, target_name, &ctx->target);
@ -214,13 +215,13 @@ gsskrb5_get_creds(
0,
ccache,
&this_cred,
cred);
&ctx->kcred);
if (kret) {
*minor_status = kret;
return GSS_S_FAILURE;
}
ctx->lifetime = (*cred)->times.endtime;
ctx->lifetime = ctx->kcred->times.endtime;
ret = _gsskrb5_lifetime_left(minor_status, context,
ctx->lifetime, &lifetime_rec);
@ -427,11 +428,11 @@ init_auth
*/
ret = gsskrb5_get_creds(minor_status, context, ctx->ccache,
ctx, name, 0, time_req,
time_rec, &ctx->kcred);
time_rec);
if (ret && allow_dns)
ret = gsskrb5_get_creds(minor_status, context, ctx->ccache,
ctx, name, 1, time_req,
time_rec, &ctx->kcred);
time_rec);
if (ret)
goto failure;

View File

@ -132,6 +132,7 @@ _gsskrb5_pseudo_random(OM_uint32 *minor_status,
krb5_data_free(&output);
num++;
}
free(input.data);
krb5_crypto_destroy(context, crypto);

View File

@ -33,6 +33,8 @@
#include "gsskrb5_locl.h"
#ifdef HEIM_WEAK_CRYPTO
static OM_uint32
unwrap_des
(OM_uint32 * minor_status,
@ -46,8 +48,9 @@ unwrap_des
{
u_char *p, *seq;
size_t len;
MD5_CTX md5;
EVP_MD_CTX *md5;
u_char hash[16];
EVP_CIPHER_CTX des_ctx;
DES_key_schedule schedule;
DES_cblock deskey;
DES_cblock zero;
@ -98,16 +101,13 @@ unwrap_des
for (i = 0; i < sizeof(deskey); ++i)
deskey[i] ^= 0xf0;
DES_set_key_unchecked (&deskey, &schedule);
memset (&zero, 0, sizeof(zero));
DES_cbc_encrypt ((void *)p,
(void *)p,
input_message_buffer->length - len,
&schedule,
&zero,
DES_DECRYPT);
memset (deskey, 0, sizeof(deskey));
EVP_CIPHER_CTX_init(&des_ctx);
EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, deskey, zero, 0);
EVP_Cipher(&des_ctx, p, p, input_message_buffer->length - len);
EVP_CIPHER_CTX_cleanup(&des_ctx);
memset (&schedule, 0, sizeof(schedule));
}
@ -122,17 +122,19 @@ unwrap_des
return ret;
}
MD5_Init (&md5);
MD5_Update (&md5, p - 24, 8);
MD5_Update (&md5, p, input_message_buffer->length - len);
MD5_Final (hash, &md5);
md5 = EVP_MD_CTX_create();
EVP_DigestInit_ex(md5, EVP_md5(), NULL);
EVP_DigestUpdate(md5, p - 24, 8);
EVP_DigestUpdate(md5, p, input_message_buffer->length - len);
EVP_DigestFinal_ex(md5, hash, NULL);
EVP_MD_CTX_destroy(md5);
memset (&zero, 0, sizeof(zero));
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
DES_set_key_unchecked (&deskey, &schedule);
DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
&schedule, &zero);
if (memcmp (p - 8, hash, 8) != 0)
if (ct_memcmp (p - 8, hash, 8) != 0)
return GSS_S_BAD_MIC;
/* verify sequence number */
@ -140,9 +142,11 @@ unwrap_des
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
p -= 16;
DES_set_key_unchecked (&deskey, &schedule);
DES_cbc_encrypt ((void *)p, (void *)p, 8,
&schedule, (DES_cblock *)hash, DES_DECRYPT);
EVP_CIPHER_CTX_init(&des_ctx);
EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, hash, 0);
EVP_Cipher(&des_ctx, p, p, 8);
EVP_CIPHER_CTX_cleanup(&des_ctx);
memset (deskey, 0, sizeof(deskey));
memset (&schedule, 0, sizeof(schedule));
@ -151,9 +155,9 @@ unwrap_des
_gsskrb5_decode_om_uint32(seq, &seq_number);
if (context_handle->more_flags & LOCAL)
cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4);
cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4);
else
cmp = memcmp(&seq[4], "\x00\x00\x00\x00", 4);
cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4);
if (cmp != 0) {
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
@ -180,6 +184,7 @@ unwrap_des
output_message_buffer->length);
return GSS_S_COMPLETE;
}
#endif
static OM_uint32
unwrap_des3
@ -224,16 +229,16 @@ unwrap_des3
if (memcmp (p, "\x04\x00", 2) != 0) /* HMAC SHA1 DES3_KD */
return GSS_S_BAD_SIG;
p += 2;
if (memcmp (p, "\x02\x00", 2) == 0) {
if (ct_memcmp (p, "\x02\x00", 2) == 0) {
cstate = 1;
} else if (memcmp (p, "\xff\xff", 2) == 0) {
} else if (ct_memcmp (p, "\xff\xff", 2) == 0) {
cstate = 0;
} else
return GSS_S_BAD_MIC;
p += 2;
if(conf_state != NULL)
*conf_state = cstate;
if (memcmp (p, "\xff\xff", 2) != 0)
if (ct_memcmp (p, "\xff\xff", 2) != 0)
return GSS_S_DEFECTIVE_TOKEN;
p += 2;
p += 28;
@ -314,9 +319,9 @@ unwrap_des3
_gsskrb5_decode_om_uint32(seq, &seq_number);
if (context_handle->more_flags & LOCAL)
cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4);
cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4);
else
cmp = memcmp(&seq[4], "\x00\x00\x00\x00", 4);
cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4);
krb5_data_free (&seq_data);
if (cmp != 0) {
@ -414,9 +419,13 @@ OM_uint32 _gsskrb5_unwrap
switch (keytype) {
case KEYTYPE_DES :
#ifdef HEIM_WEAK_CRYPTO
ret = unwrap_des (minor_status, ctx,
input_message_buffer, output_message_buffer,
conf_state, qop_state, key);
#else
ret = GSS_S_FAILURE;
#endif
break;
case KEYTYPE_DES3 :
ret = unwrap_des3 (minor_status, ctx, context,

View File

@ -33,6 +33,8 @@
#include "gsskrb5_locl.h"
#ifdef HEIM_WEAK_CRYPTO
static OM_uint32
verify_mic_des
(OM_uint32 * minor_status,
@ -46,9 +48,10 @@ verify_mic_des
)
{
u_char *p;
MD5_CTX md5;
EVP_MD_CTX *md5;
u_char hash[16], *seq;
DES_key_schedule schedule;
EVP_CIPHER_CTX des_ctx;
DES_cblock zero;
DES_cblock deskey;
uint32_t seq_number;
@ -72,11 +75,12 @@ verify_mic_des
p += 16;
/* verify checksum */
MD5_Init (&md5);
MD5_Update (&md5, p - 24, 8);
MD5_Update (&md5, message_buffer->value,
message_buffer->length);
MD5_Final (hash, &md5);
md5 = EVP_MD_CTX_create();
EVP_DigestInit_ex(md5, EVP_md5(), NULL);
EVP_DigestUpdate(md5, p - 24, 8);
EVP_DigestUpdate(md5, message_buffer->value, message_buffer->length);
EVP_DigestFinal_ex(md5, hash, NULL);
EVP_MD_CTX_destroy(md5);
memset (&zero, 0, sizeof(zero));
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
@ -84,7 +88,7 @@ verify_mic_des
DES_set_key_unchecked (&deskey, &schedule);
DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
&schedule, &zero);
if (memcmp (p - 8, hash, 8) != 0) {
if (ct_memcmp (p - 8, hash, 8) != 0) {
memset (deskey, 0, sizeof(deskey));
memset (&schedule, 0, sizeof(schedule));
return GSS_S_BAD_MIC;
@ -95,9 +99,11 @@ verify_mic_des
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
p -= 16;
DES_set_key_unchecked (&deskey, &schedule);
DES_cbc_encrypt ((void *)p, (void *)p, 8,
&schedule, (DES_cblock *)hash, DES_DECRYPT);
EVP_CIPHER_CTX_init(&des_ctx);
EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, hash, 0);
EVP_Cipher(&des_ctx, p, p, 8);
EVP_CIPHER_CTX_cleanup(&des_ctx);
memset (deskey, 0, sizeof(deskey));
memset (&schedule, 0, sizeof(schedule));
@ -106,9 +112,9 @@ verify_mic_des
_gsskrb5_decode_om_uint32(seq, &seq_number);
if (context_handle->more_flags & LOCAL)
cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4);
cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4);
else
cmp = memcmp(&seq[4], "\x00\x00\x00\x00", 4);
cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4);
if (cmp != 0) {
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
@ -125,6 +131,7 @@ verify_mic_des
return GSS_S_COMPLETE;
}
#endif
static OM_uint32
verify_mic_des3
@ -207,9 +214,9 @@ retry:
_gsskrb5_decode_om_uint32(seq, &seq_number);
if (context_handle->more_flags & LOCAL)
cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4);
cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4);
else
cmp = memcmp(&seq[4], "\x00\x00\x00\x00", 4);
cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4);
krb5_data_free (&seq_data);
if (cmp != 0) {
@ -292,9 +299,13 @@ _gsskrb5_verify_mic_internal
krb5_enctype_to_keytype (context, key->keytype, &keytype);
switch (keytype) {
case KEYTYPE_DES :
#ifdef HEIM_WEAK_CRYPTO
ret = verify_mic_des (minor_status, ctx, context,
message_buffer, token_buffer, qop_state, key,
type);
#else
ret = GSS_S_FAILURE;
#endif
break;
case KEYTYPE_DES3 :
ret = verify_mic_des3 (minor_status, ctx, context,

View File

@ -168,7 +168,11 @@ _gsskrb5_wrap_size_limit (
switch (keytype) {
case KEYTYPE_DES :
#ifdef HEIM_WEAK_CRYPTO
ret = sub_wrap_size(req_output_size, max_input_size, 8, 22);
#else
ret = GSS_S_FAILURE;
#endif
break;
case KEYTYPE_ARCFOUR:
case KEYTYPE_ARCFOUR_56:
@ -188,6 +192,8 @@ _gsskrb5_wrap_size_limit (
return ret;
}
#ifdef HEIM_WEAK_CRYPTO
static OM_uint32
wrap_des
(OM_uint32 * minor_status,
@ -202,9 +208,10 @@ wrap_des
)
{
u_char *p;
MD5_CTX md5;
EVP_MD_CTX *md5;
u_char hash[16];
DES_key_schedule schedule;
EVP_CIPHER_CTX des_ctx;
DES_cblock deskey;
DES_cblock zero;
int i;
@ -262,10 +269,12 @@ wrap_des
memset (p + 8 + input_message_buffer->length, padlength, padlength);
/* checksum */
MD5_Init (&md5);
MD5_Update (&md5, p - 24, 8);
MD5_Update (&md5, p, datalen);
MD5_Final (hash, &md5);
md5 = EVP_MD_CTX_create();
EVP_DigestInit_ex(md5, EVP_md5(), NULL);
EVP_DigestUpdate(md5, p - 24, 8);
EVP_DigestUpdate(md5, p, datalen);
EVP_DigestFinal_ex(md5, hash, NULL);
EVP_MD_CTX_destroy(md5);
memset (&zero, 0, sizeof(zero));
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
@ -289,9 +298,10 @@ wrap_des
(ctx->more_flags & LOCAL) ? 0 : 0xFF,
4);
DES_set_key_unchecked (&deskey, &schedule);
DES_cbc_encrypt ((void *)p, (void *)p, 8,
&schedule, (DES_cblock *)(p + 8), DES_ENCRYPT);
EVP_CIPHER_CTX_init(&des_ctx);
EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, p + 8, 1);
EVP_Cipher(&des_ctx, p, p, 8);
EVP_CIPHER_CTX_cleanup(&des_ctx);
krb5_auth_con_setlocalseqnumber (context,
ctx->auth_context,
@ -306,14 +316,11 @@ wrap_des
for (i = 0; i < sizeof(deskey); ++i)
deskey[i] ^= 0xf0;
DES_set_key_unchecked (&deskey, &schedule);
memset (&zero, 0, sizeof(zero));
DES_cbc_encrypt ((void *)p,
(void *)p,
datalen,
&schedule,
&zero,
DES_ENCRYPT);
EVP_CIPHER_CTX_init(&des_ctx);
EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, deskey, zero, 1);
EVP_Cipher(&des_ctx, p, p, datalen);
EVP_CIPHER_CTX_cleanup(&des_ctx);
}
memset (deskey, 0, sizeof(deskey));
memset (&schedule, 0, sizeof(schedule));
@ -324,6 +331,8 @@ wrap_des
return GSS_S_COMPLETE;
}
#endif
static OM_uint32
wrap_des3
(OM_uint32 * minor_status,
@ -552,9 +561,13 @@ OM_uint32 _gsskrb5_wrap
switch (keytype) {
case KEYTYPE_DES :
#ifdef HEIM_WEAK_CRYPTO
ret = wrap_des (minor_status, ctx, context, conf_req_flag,
qop_req, input_message_buffer, conf_state,
output_message_buffer, key);
#else
ret = GSS_S_FAILURE;
#endif
break;
case KEYTYPE_DES3 :
ret = wrap_des3 (minor_status, ctx, context, conf_req_flag,

View File

@ -1,8 +1,6 @@
#include "mech_locl.h"
#include "heim_threads.h"
RCSID("$Id$");
struct mg_thread_ctx {
gss_OID mech;
OM_uint32 maj_stat;

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
static OM_uint32
parse_header(const gss_buffer_t input_token, gss_OID mech_oid)
@ -161,6 +160,7 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
struct _gss_mechanism_cred *mc;
gss_cred_id_t acceptor_mc, delegated_mc;
gss_name_t src_mn;
gss_OID mech_ret_type = NULL;
*minor_status = 0;
if (src_name)
@ -228,7 +228,7 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
input_token,
input_chan_bindings,
&src_mn,
mech_type,
&mech_ret_type,
output_token,
&mech_ret_flags,
time_rec,
@ -241,6 +241,9 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
return (major_status);
}
if (mech_type)
*mech_type = mech_ret_type;
if (src_name && src_mn) {
/*
* Make a new name and mark it as an MN.
@ -262,6 +265,15 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
m->gm_release_cred(minor_status, &delegated_mc);
if (ret_flags)
*ret_flags &= ~GSS_C_DELEG_FLAG;
} else if (gss_oid_equal(mech_ret_type, &m->gm_mech_oid) == 0) {
/*
* If the returned mech_type is not the same
* as the mech, assume its pseudo mech type
* and the returned type is already a
* mech-glue object
*/
*delegated_cred_handle = delegated_mc;
} else if (delegated_mc) {
struct _gss_cred *dcred;
struct _gss_mechanism_cred *dmc;

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_acquire_cred(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
static struct _gss_mechanism_cred *
_gss_copy_cred(struct _gss_mechanism_cred *mc)

View File

@ -32,7 +32,24 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
/**
* Add a oid to the oid set, function does not make a copy of the oid,
* so the pointer to member_oid needs to be stable for the whole time
* oid_set is used.
*
* If there is a duplicate member of the oid, the new member is not
* added to to the set.
*
* @param minor_status minor status code.
* @param member_oid member to add to the oid set
* @param oid_set oid set to add the member too
*
* @returns a gss_error code, see gss_display_status() about printing
* the error code.
*
* @ingroup gssapi
*/
OM_uint32 GSSAPI_LIB_FUNCTION
gss_add_oid_set_member (OM_uint32 * minor_status,

View File

@ -31,7 +31,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_create_empty_buffer_set

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
/**
* gss_canonicalize_name takes a Internal Name (IN) and converts in into a

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_compare_name(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_context_time(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_create_empty_oid_set(OM_uint32 *minor_status,

View File

@ -32,7 +32,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_decapsulate_token(gss_buffer_t input_token,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_delete_sec_context(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_display_name(OM_uint32 *minor_status,

View File

@ -59,7 +59,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
static const char *
calling_error(OM_uint32 v)

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 gss_duplicate_name(OM_uint32 *minor_status,
const gss_name_t src_name,

View File

@ -32,7 +32,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 gss_duplicate_oid (
OM_uint32 *minor_status,

View File

@ -32,7 +32,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_encapsulate_token(gss_buffer_t input_token,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_export_name(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_export_sec_context(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_get_mic(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
static OM_uint32
_gss_import_export_name(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_import_sec_context(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_indicate_mechs(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
static gss_cred_id_t
_gss_mech_cred_find(gss_cred_id_t cred_handle, gss_OID mech_type)
@ -119,7 +118,10 @@ gss_init_sec_context(OM_uint32 * minor_status,
/*
* If we have a cred, find the cred for this mechanism.
*/
cred_handle = _gss_mech_cred_find(initiator_cred_handle, mech_type);
if (m->gm_flags & GM_USE_MG_CRED)
cred_handle = initiator_cred_handle;
else
cred_handle = _gss_mech_cred_find(initiator_cred_handle, mech_type);
major_status = m->gm_init_sec_context(minor_status,
cred_handle,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_inquire_context(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
#define AUSAGE 1
#define IUSAGE 2

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_inquire_cred_by_mech(OM_uint32 *minor_status,

View File

@ -31,7 +31,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_inquire_cred_by_oid (OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_inquire_mechs_for_name(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_inquire_names_for_mech(OM_uint32 *minor_status,

View File

@ -31,7 +31,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_inquire_sec_context_by_oid (OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
#include <krb5.h>
#include <roken.h>

View File

@ -28,7 +28,6 @@
#include "mech_locl.h"
#include <heim_threads.h>
RCSID("$Id$");
#ifndef _PATH_GSS_MECH
#define _PATH_GSS_MECH "/etc/gss/mech"
@ -272,6 +271,7 @@ _gss_load_mech(void)
free(m);
continue;
}
m->gm_mech.gm_flags = 0;
major_status = gss_add_oid_set_member(&minor_status,
&m->gm_mech.gm_mech_oid, &_gss_mech_oids);

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32
_gss_find_mn(OM_uint32 *minor_status, struct _gss_name *name, gss_OID mech,

View File

@ -32,7 +32,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
int GSSAPI_LIB_FUNCTION
gss_oid_equal(const gss_OID a, const gss_OID b)

View File

@ -32,7 +32,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_oid_to_str(OM_uint32 *minor_status, gss_OID oid, gss_buffer_t oid_str)

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_process_context_token(OM_uint32 *minor_status,

View File

@ -34,7 +34,6 @@
/* $Id$ */
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_pseudo_random(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_release_buffer(OM_uint32 *minor_status,

View File

@ -27,7 +27,28 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
/**
* Release a credentials
*
* Its ok to release the GSS_C_NO_CREDENTIAL/NULL credential, it will
* return a GSS_S_COMPLETE error code. On return cred_handle is set ot
* GSS_C_NO_CREDENTIAL.
*
* Example:
*
* @code
* gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
* major = gss_release_cred(&minor, &cred);
* @endcode
*
* @param minor_status minor status return code, mech specific
* @param cred_handle a pointer to the credential too release
*
* @return an gssapi error code
*
* @ingroup gssapi
*/
OM_uint32 GSSAPI_LIB_FUNCTION
gss_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle)

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_release_name(OM_uint32 *minor_status,

View File

@ -33,7 +33,6 @@
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_release_oid(OM_uint32 *minor_status, gss_OID *oid)

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_release_oid_set(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_seal(OM_uint32 *minor_status,

View File

@ -31,7 +31,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_set_cred_option (OM_uint32 *minor_status,

View File

@ -31,7 +31,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_set_sec_context_option (OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_sign(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_test_oid_set_member(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_unseal(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_unwrap(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32
_gss_copy_oid(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_verify(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_verify_mic(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_wrap(OM_uint32 *minor_status,

View File

@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_wrap_size_limit(OM_uint32 *minor_status,

View File

@ -496,7 +496,6 @@ acceptor_start
gss_buffer_desc mech_buf;
gss_OID preferred_mech_type = GSS_C_NO_OID;
gssspnego_ctx ctx;
gssspnego_cred acceptor_cred = (gssspnego_cred)acceptor_cred_handle;
int get_mic = 0;
int first_ok = 0;
@ -564,25 +563,18 @@ acceptor_start
&preferred_mech_type);
if (ret == 0 && ni->mechToken != NULL) {
gss_cred_id_t mech_delegated_cred = GSS_C_NO_CREDENTIAL;
gss_cred_id_t mech_cred;
gss_buffer_desc ibuf;
ibuf.length = ni->mechToken->length;
ibuf.value = ni->mechToken->data;
mech_input_token = &ibuf;
if (acceptor_cred != NULL)
mech_cred = acceptor_cred->negotiated_cred_id;
else
mech_cred = GSS_C_NO_CREDENTIAL;
if (ctx->mech_src_name != GSS_C_NO_NAME)
gss_release_name(&junk, &ctx->mech_src_name);
ret = gss_accept_sec_context(minor_status,
&ctx->negotiated_ctx_id,
mech_cred,
acceptor_cred_handle,
mech_input_token,
input_chan_bindings,
&ctx->mech_src_name,
@ -590,18 +582,10 @@ acceptor_start
&mech_output_token,
&ctx->mech_flags,
&ctx->mech_time_rec,
&mech_delegated_cred);
if (mech_delegated_cred && delegated_cred_handle) {
_gss_spnego_alloc_cred(&junk,
mech_delegated_cred,
delegated_cred_handle);
} else if (mech_delegated_cred != GSS_C_NO_CREDENTIAL)
gss_release_cred(&junk, &mech_delegated_cred);
delegated_cred_handle);
if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) {
ctx->preferred_mech_type = preferred_mech_type;
ctx->negotiated_mech_type = preferred_mech_type;
if (ret == GSS_S_COMPLETE)
ctx->open = 1;
@ -646,7 +630,6 @@ acceptor_start
}
ctx->preferred_mech_type = preferred_mech_type;
ctx->negotiated_mech_type = preferred_mech_type;
}
/*
@ -719,7 +702,7 @@ acceptor_continue
gss_cred_id_t *delegated_cred_handle
)
{
OM_uint32 ret, ret2, minor, junk;
OM_uint32 ret, ret2, minor;
NegotiationToken nt;
size_t nt_len;
NegTokenResp *na;
@ -728,7 +711,6 @@ acceptor_continue
gss_buffer_t mech_output_token = GSS_C_NO_BUFFER;
gss_buffer_desc mech_buf;
gssspnego_ctx ctx;
gssspnego_cred acceptor_cred = (gssspnego_cred)acceptor_cred_handle;
mech_buf.value = NULL;
@ -774,20 +756,13 @@ acceptor_continue
}
if (mech_input_token != GSS_C_NO_BUFFER) {
gss_cred_id_t mech_cred;
gss_cred_id_t mech_delegated_cred = GSS_C_NO_CREDENTIAL;
if (acceptor_cred != NULL)
mech_cred = acceptor_cred->negotiated_cred_id;
else
mech_cred = GSS_C_NO_CREDENTIAL;
if (ctx->mech_src_name != GSS_C_NO_NAME)
gss_release_name(&minor, &ctx->mech_src_name);
ret = gss_accept_sec_context(&minor,
&ctx->negotiated_ctx_id,
mech_cred,
acceptor_cred_handle,
mech_input_token,
input_chan_bindings,
&ctx->mech_src_name,
@ -795,14 +770,7 @@ acceptor_continue
&obuf,
&ctx->mech_flags,
&ctx->mech_time_rec,
&mech_delegated_cred);
if (mech_delegated_cred && delegated_cred_handle) {
_gss_spnego_alloc_cred(&junk,
mech_delegated_cred,
delegated_cred_handle);
} else if (mech_delegated_cred != GSS_C_NO_CREDENTIAL)
gss_release_cred(&junk, &mech_delegated_cred);
delegated_cred_handle);
if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) {
mech_output_token = &obuf;

View File

@ -142,7 +142,6 @@ OM_uint32 _gss_spnego_internal_delete_sec_context
HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
free(ctx);
*context_handle = NULL;
return ret;
}
@ -236,7 +235,7 @@ _gss_spnego_indicate_mechtypelist (OM_uint32 *minor_status,
gss_name_t target_name,
OM_uint32 (*func)(gss_name_t, gss_OID),
int includeMSCompatOID,
const gssspnego_cred cred_handle,
const gss_cred_id_t cred_handle,
MechTypeList *mechtypelist,
gss_OID *preferred_mech)
{
@ -248,9 +247,9 @@ _gss_spnego_indicate_mechtypelist (OM_uint32 *minor_status,
mechtypelist->len = 0;
mechtypelist->val = NULL;
if (cred_handle != NULL) {
if (cred_handle) {
ret = gss_inquire_cred(minor_status,
cred_handle->negotiated_cred_id,
cred_handle,
NULL,
NULL,
NULL,

View File

@ -643,84 +643,70 @@ OM_uint32 _gss_spnego_duplicate_name (
return gss_duplicate_name(minor_status, src_name, dest_name);
}
OM_uint32
_gss_spnego_wrap_iov(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
int * conf_state,
gss_iov_buffer_desc *iov,
int iov_count)
{
gssspnego_ctx ctx = (gssspnego_ctx)context_handle;
*minor_status = 0;
if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
return GSS_S_NO_CONTEXT;
return gss_wrap_iov(minor_status, ctx->negotiated_ctx_id,
conf_req_flag, qop_req, conf_state,
iov, iov_count);
}
OM_uint32
_gss_spnego_unwrap_iov(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
int *conf_state,
gss_qop_t *qop_state,
gss_iov_buffer_desc *iov,
int iov_count)
{
gssspnego_ctx ctx = (gssspnego_ctx)context_handle;
*minor_status = 0;
if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
return GSS_S_NO_CONTEXT;
return gss_unwrap_iov(minor_status,
ctx->negotiated_ctx_id,
conf_state, qop_state,
iov, iov_count);
}
OM_uint32
_gss_spnego_wrap_iov_length(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
int *conf_state,
gss_iov_buffer_desc *iov,
int iov_count)
{
gssspnego_ctx ctx = (gssspnego_ctx)context_handle;
*minor_status = 0;
if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
return GSS_S_NO_CONTEXT;
return gss_wrap_iov_length(minor_status, ctx->negotiated_ctx_id,
conf_req_flag, qop_req, conf_state,
iov, iov_count);
}
#if 0
OM_uint32 _gss_spnego_unwrap_ex
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t token_header_buffer,
const gss_buffer_t associated_data_buffer,
const gss_buffer_t input_message_buffer,
gss_buffer_t output_message_buffer,
int * conf_state,
gss_qop_t * qop_state)
{
gssspnego_ctx ctx;
*minor_status = 0;
if (context_handle == GSS_C_NO_CONTEXT) {
return GSS_S_NO_CONTEXT;
}
ctx = (gssspnego_ctx)context_handle;
if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
return GSS_S_NO_CONTEXT;
}
return gss_unwrap_ex(minor_status,
ctx->negotiated_ctx_id,
token_header_buffer,
associated_data_buffer,
input_message_buffer,
output_message_buffer,
conf_state,
qop_state);
}
OM_uint32 _gss_spnego_wrap_ex
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
const gss_buffer_t associated_data_buffer,
const gss_buffer_t input_message_buffer,
int * conf_state,
gss_buffer_t output_token_buffer,
gss_buffer_t output_message_buffer
)
{
gssspnego_ctx ctx;
*minor_status = 0;
if (context_handle == GSS_C_NO_CONTEXT) {
return GSS_S_NO_CONTEXT;
}
ctx = (gssspnego_ctx)context_handle;
if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
return GSS_S_NO_CONTEXT;
}
if ((ctx->mech_flags & GSS_C_DCE_STYLE) == 0 &&
associated_data_buffer->length != input_message_buffer->length) {
*minor_status = EINVAL;
return GSS_S_BAD_QOP;
}
return gss_wrap_ex(minor_status,
ctx->negotiated_ctx_id,
conf_req_flag,
qop_req,
associated_data_buffer,
input_message_buffer,
conf_state,
output_token_buffer,
output_message_buffer);
}
OM_uint32 _gss_spnego_complete_auth_token
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,

View File

@ -37,50 +37,20 @@ RCSID("$Id$");
OM_uint32
_gss_spnego_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle)
{
gssspnego_cred cred;
OM_uint32 ret;
*minor_status = 0;
if (*cred_handle == GSS_C_NO_CREDENTIAL) {
if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL)
return GSS_S_COMPLETE;
}
cred = (gssspnego_cred)*cred_handle;
ret = gss_release_cred(minor_status, &cred->negotiated_cred_id);
ret = gss_release_cred(minor_status, cred_handle);
free(cred);
*cred_handle = GSS_C_NO_CREDENTIAL;
return ret;
}
OM_uint32
_gss_spnego_alloc_cred(OM_uint32 *minor_status,
gss_cred_id_t mech_cred_handle,
gss_cred_id_t *cred_handle)
{
gssspnego_cred cred;
if (*cred_handle != GSS_C_NO_CREDENTIAL) {
*minor_status = EINVAL;
return GSS_S_FAILURE;
}
cred = calloc(1, sizeof(*cred));
if (cred == NULL) {
*cred_handle = GSS_C_NO_CREDENTIAL;
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
cred->negotiated_cred_id = mech_cred_handle;
*cred_handle = (gss_cred_id_t)cred;
return GSS_S_COMPLETE;
}
/*
* For now, just a simple wrapper that avoids recursion. When
* we support gss_{get,set}_neg_mechs() we will need to expose
@ -103,8 +73,6 @@ OM_uint32 _gss_spnego_acquire_cred
gss_OID_set_desc actual_desired_mechs;
gss_OID_set mechs;
int i, j;
gss_cred_id_t cred_handle = GSS_C_NO_CREDENTIAL;
gssspnego_cred cred;
*output_cred_handle = GSS_C_NO_CREDENTIAL;
@ -140,22 +108,14 @@ OM_uint32 _gss_spnego_acquire_cred
}
actual_desired_mechs.count = j;
ret = _gss_spnego_alloc_cred(minor_status, GSS_C_NO_CREDENTIAL,
&cred_handle);
if (ret != GSS_S_COMPLETE)
goto out;
cred = (gssspnego_cred)cred_handle;
ret = gss_acquire_cred(minor_status, name,
time_req, &actual_desired_mechs,
cred_usage,
&cred->negotiated_cred_id,
output_cred_handle,
actual_mechs, time_rec);
if (ret != GSS_S_COMPLETE)
goto out;
*output_cred_handle = cred_handle;
out:
gss_release_name(minor_status, &name);
gss_release_oid_set(&tmp, &mechs);
@ -163,7 +123,7 @@ out:
free(actual_desired_mechs.elements);
}
if (ret != GSS_S_COMPLETE) {
_gss_spnego_release_cred(&tmp, &cred_handle);
_gss_spnego_release_cred(&tmp, output_cred_handle);
}
return ret;
@ -178,7 +138,6 @@ OM_uint32 _gss_spnego_inquire_cred
gss_OID_set * mechanisms
)
{
gssspnego_cred cred;
spnego_name sname = NULL;
OM_uint32 ret;
@ -195,10 +154,8 @@ OM_uint32 _gss_spnego_inquire_cred
}
}
cred = (gssspnego_cred)cred_handle;
ret = gss_inquire_cred(minor_status,
cred->negotiated_cred_id,
cred_handle,
sname ? &sname->mech : NULL,
lifetime,
cred_usage,
@ -214,55 +171,6 @@ OM_uint32 _gss_spnego_inquire_cred
return ret;
}
OM_uint32 _gss_spnego_add_cred (
OM_uint32 * minor_status,
const gss_cred_id_t input_cred_handle,
const gss_name_t desired_name,
const gss_OID desired_mech,
gss_cred_usage_t cred_usage,
OM_uint32 initiator_time_req,
OM_uint32 acceptor_time_req,
gss_cred_id_t * output_cred_handle,
gss_OID_set * actual_mechs,
OM_uint32 * initiator_time_rec,
OM_uint32 * acceptor_time_rec
)
{
gss_cred_id_t spnego_output_cred_handle = GSS_C_NO_CREDENTIAL;
OM_uint32 ret, tmp;
gssspnego_cred input_cred, output_cred;
*output_cred_handle = GSS_C_NO_CREDENTIAL;
ret = _gss_spnego_alloc_cred(minor_status, GSS_C_NO_CREDENTIAL,
&spnego_output_cred_handle);
if (ret)
return ret;
input_cred = (gssspnego_cred)input_cred_handle;
output_cred = (gssspnego_cred)spnego_output_cred_handle;
ret = gss_add_cred(minor_status,
input_cred->negotiated_cred_id,
desired_name,
desired_mech,
cred_usage,
initiator_time_req,
acceptor_time_req,
&output_cred->negotiated_cred_id,
actual_mechs,
initiator_time_rec,
acceptor_time_rec);
if (ret) {
_gss_spnego_release_cred(&tmp, &spnego_output_cred_handle);
return ret;
}
*output_cred_handle = spnego_output_cred_handle;
return GSS_S_COMPLETE;
}
OM_uint32 _gss_spnego_inquire_cred_by_mech (
OM_uint32 * minor_status,
const gss_cred_id_t cred_handle,
@ -273,7 +181,6 @@ OM_uint32 _gss_spnego_inquire_cred_by_mech (
gss_cred_usage_t * cred_usage
)
{
gssspnego_cred cred;
spnego_name sname = NULL;
OM_uint32 ret;
@ -290,10 +197,8 @@ OM_uint32 _gss_spnego_inquire_cred_by_mech (
}
}
cred = (gssspnego_cred)cred_handle;
ret = gss_inquire_cred_by_mech(minor_status,
cred->negotiated_cred_id,
cred_handle,
mech_type,
sname ? &sname->mech : NULL,
initiator_lifetime,
@ -317,17 +222,15 @@ OM_uint32 _gss_spnego_inquire_cred_by_oid
const gss_OID desired_object,
gss_buffer_set_t *data_set)
{
gssspnego_cred cred;
OM_uint32 ret;
if (cred_handle == GSS_C_NO_CREDENTIAL) {
*minor_status = 0;
return GSS_S_NO_CRED;
}
cred = (gssspnego_cred)cred_handle;
ret = gss_inquire_cred_by_oid(minor_status,
cred->negotiated_cred_id,
cred_handle,
desired_object,
data_set);
@ -340,16 +243,13 @@ _gss_spnego_set_cred_option (OM_uint32 *minor_status,
const gss_OID object,
const gss_buffer_t value)
{
gssspnego_cred cred;
if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) {
*minor_status = 0;
return GSS_S_NO_CRED;
}
cred = (gssspnego_cred)*cred_handle;
return gss_set_cred_option(minor_status,
&cred->negotiated_cred_id,
cred_handle,
object,
value);
}
@ -360,9 +260,7 @@ _gss_spnego_export_cred (OM_uint32 *minor_status,
gss_cred_id_t cred_handle,
gss_buffer_t value)
{
gssspnego_cred cred = (gssspnego_cred)cred_handle;
return gss_export_cred(minor_status, cred->negotiated_cred_id, value);
return gss_export_cred(minor_status, cred_handle, value);
}
OM_uint32
@ -370,23 +268,6 @@ _gss_spnego_import_cred (OM_uint32 *minor_status,
gss_buffer_t value,
gss_cred_id_t *cred_handle)
{
gssspnego_cred cred;
OM_uint32 major;
*cred_handle = GSS_C_NO_CREDENTIAL;
cred = calloc(1, sizeof(*cred));
if (cred == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
major = gss_import_cred(minor_status, value, &cred->negotiated_cred_id);
if (major == GSS_S_COMPLETE)
*cred_handle = (gss_cred_id_t)cred;
else
free(cred);
return major;
return gss_import_cred(minor_status, value, cred_handle);
}

View File

@ -46,6 +46,7 @@ static gssapi_mech_interface_desc spnego_mech = {
GMI_VERSION,
"spnego",
{6, (void *)"\x2b\x06\x01\x05\x05\x02"},
0,
_gss_spnego_acquire_cred,
_gss_spnego_release_cred,
_gss_spnego_init_sec_context,
@ -67,7 +68,7 @@ static gssapi_mech_interface_desc spnego_mech = {
_gss_spnego_inquire_cred,
_gss_spnego_inquire_context,
_gss_spnego_wrap_size_limit,
_gss_spnego_add_cred,
gss_add_cred,
_gss_spnego_inquire_cred_by_mech,
_gss_spnego_export_sec_context,
_gss_spnego_import_sec_context,
@ -80,9 +81,9 @@ static gssapi_mech_interface_desc spnego_mech = {
_gss_spnego_set_sec_context_option,
_gss_spnego_set_cred_option,
_gss_spnego_pseudo_random,
NULL,
NULL,
NULL,
_gss_spnego_wrap_iov,
_gss_spnego_unwrap_iov,
_gss_spnego_wrap_iov_length,
NULL,
_gss_spnego_export_cred,
_gss_spnego_import_cred

View File

@ -179,7 +179,7 @@ spnego_reply_internal(OM_uint32 *minor_status,
static OM_uint32
spnego_initial
(OM_uint32 * minor_status,
gssspnego_cred cred,
gss_cred_id_t cred,
gss_ctx_id_t * context_handle,
const gss_name_t target_name,
const gss_OID mech_type,
@ -254,8 +254,7 @@ spnego_initial
/* generate optimistic token */
sub = gss_init_sec_context(&minor,
(cred != NULL) ? cred->negotiated_cred_id :
GSS_C_NO_CREDENTIAL,
cred,
&ctx->negotiated_ctx_id,
ctx->target_name,
ctx->preferred_mech_type,
@ -377,7 +376,7 @@ spnego_initial
static OM_uint32
spnego_reply
(OM_uint32 * minor_status,
const gssspnego_cred cred,
const gss_cred_id_t cred,
gss_ctx_id_t * context_handle,
const gss_name_t target_name,
const gss_OID mech_type,
@ -498,8 +497,7 @@ spnego_reply
/* Fall through as if the negotiated mechanism
was requested explicitly */
ret = gss_init_sec_context(&minor,
(cred != NULL) ? cred->negotiated_cred_id :
GSS_C_NO_CREDENTIAL,
cred,
&ctx->negotiated_ctx_id,
ctx->target_name,
&mech,
@ -629,11 +627,9 @@ OM_uint32 _gss_spnego_init_sec_context
OM_uint32 * time_rec
)
{
gssspnego_cred cred = (gssspnego_cred)initiator_cred_handle;
if (*context_handle == GSS_C_NO_CONTEXT)
return spnego_initial (minor_status,
cred,
initiator_cred_handle,
context_handle,
target_name,
mech_type,
@ -647,7 +643,7 @@ OM_uint32 _gss_spnego_init_sec_context
time_rec);
else
return spnego_reply (minor_status,
cred,
initiator_cred_handle,
context_handle,
target_name,
mech_type,

View File

@ -73,10 +73,6 @@
#define ALLOC(X, N) (X) = calloc((N), sizeof(*(X)))
typedef struct {
gss_cred_id_t negotiated_cred_id;
} *gssspnego_cred;
typedef struct {
MechTypeList initiator_mech_types;
gss_OID preferred_mech_type;

View File

@ -182,6 +182,7 @@ DES_is_weak_key(DES_cblock *key)
{
int i;
/* Not constant time size if the key is weak, the app should not use it. */
for (i = 0; i < sizeof(weak_keys)/sizeof(weak_keys[0]); i++) {
if (memcmp(weak_keys[i], key, DES_CBLOCK_LEN) == 0)
return 1;

View File

@ -1,273 +0,0 @@
/*
* Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#define HC_DEPRECATED
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <krb5-types.h>
#if defined(BUILD_KRB5_LIB) && defined(HAVE_OPENSSL)
#include <openssl/evp.h>
#include <openssl/aes.h>
#define _hc_EVP_hcrypto_aes_128_cts _krb5_EVP_hcrypto_aes_128_cts
#define _hc_EVP_hcrypto_aes_192_cts _krb5_EVP_hcrypto_aes_192_cts
#define _hc_EVP_hcrypto_aes_256_cts _krb5_EVP_hcrypto_aes_256_cts
const EVP_CIPHER * _krb5_EVP_hcrypto_aes_128_cts(void);
const EVP_CIPHER * _krb5_EVP_hcrypto_aes_192_cts(void);
const EVP_CIPHER * _krb5_EVP_hcrypto_aes_256_cts(void);
#else
#include <evp.h>
#include <aes.h>
#define _hc_EVP_hcrypto_aes_128_cts hc_EVP_hcrypto_aes_128_cts
#define _hc_EVP_hcrypto_aes_192_cts hc_EVP_hcrypto_aes_192_cts
#define _hc_EVP_hcrypto_aes_256_cts hc_EVP_hcrypto_aes_256_cts
#endif
/*
*
*/
static int
aes_cts_init(EVP_CIPHER_CTX *ctx,
const unsigned char * key,
const unsigned char * iv,
int encp)
{
AES_KEY *k = ctx->cipher_data;
if (ctx->encrypt)
AES_set_encrypt_key(key, ctx->cipher->key_len * 8, k);
else
AES_set_decrypt_key(key, ctx->cipher->key_len * 8, k);
return 1;
}
static void
_krb5_aes_cts_encrypt(const unsigned char *in, unsigned char *out,
size_t len, const AES_KEY *key,
unsigned char *ivec, const int encryptp)
{
unsigned char tmp[AES_BLOCK_SIZE];
int i;
/*
* In the framework of kerberos, the length can never be shorter
* then at least one blocksize.
*/
if (encryptp) {
while(len > AES_BLOCK_SIZE) {
for (i = 0; i < AES_BLOCK_SIZE; i++)
tmp[i] = in[i] ^ ivec[i];
AES_encrypt(tmp, out, key);
memcpy(ivec, out, AES_BLOCK_SIZE);
len -= AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
out += AES_BLOCK_SIZE;
}
for (i = 0; i < len; i++)
tmp[i] = in[i] ^ ivec[i];
for (; i < AES_BLOCK_SIZE; i++)
tmp[i] = 0 ^ ivec[i];
AES_encrypt(tmp, out - AES_BLOCK_SIZE, key);
memcpy(out, ivec, len);
memcpy(ivec, out - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
} else {
unsigned char tmp2[AES_BLOCK_SIZE];
unsigned char tmp3[AES_BLOCK_SIZE];
while(len > AES_BLOCK_SIZE * 2) {
memcpy(tmp, in, AES_BLOCK_SIZE);
AES_decrypt(in, out, key);
for (i = 0; i < AES_BLOCK_SIZE; i++)
out[i] ^= ivec[i];
memcpy(ivec, tmp, AES_BLOCK_SIZE);
len -= AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
out += AES_BLOCK_SIZE;
}
len -= AES_BLOCK_SIZE;
memcpy(tmp, in, AES_BLOCK_SIZE); /* save last iv */
AES_decrypt(in, tmp2, key);
memcpy(tmp3, in + AES_BLOCK_SIZE, len);
memcpy(tmp3 + len, tmp2 + len, AES_BLOCK_SIZE - len); /* xor 0 */
for (i = 0; i < len; i++)
out[i + AES_BLOCK_SIZE] = tmp2[i] ^ tmp3[i];
AES_decrypt(tmp3, out, key);
for (i = 0; i < AES_BLOCK_SIZE; i++)
out[i] ^= ivec[i];
memcpy(ivec, tmp, AES_BLOCK_SIZE);
}
}
static int
aes_cts_do_cipher(EVP_CIPHER_CTX *ctx,
unsigned char *out,
const unsigned char *in,
unsigned int len)
{
AES_KEY *k = ctx->cipher_data;
if (len < AES_BLOCK_SIZE)
abort(); /* krb5_abortx(context, "invalid use of AES_CTS_encrypt"); */
if (len == AES_BLOCK_SIZE) {
if (ctx->encrypt)
AES_encrypt(in, out, k);
else
AES_decrypt(in, out, k);
} else {
_krb5_aes_cts_encrypt(in, out, len, k, ctx->iv, ctx->encrypt);
}
return 1;
}
static int
aes_cts_cleanup(EVP_CIPHER_CTX *ctx)
{
memset(ctx->cipher_data, 0, sizeof(AES_KEY));
return 1;
}
/**
* The AES-128 cts cipher type (hcrypto)
*
* @return the AES-128 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
_hc_EVP_hcrypto_aes_128_cts(void)
{
static const EVP_CIPHER aes_128_cts = {
0,
1,
16,
16,
EVP_CIPH_CBC_MODE,
aes_cts_init,
aes_cts_do_cipher,
aes_cts_cleanup,
sizeof(AES_KEY),
NULL,
NULL,
NULL,
NULL
};
return &aes_128_cts;
}
/**
* The AES-192 cts cipher type (hcrypto)
*
* @return the AES-192 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
_hc_EVP_hcrypto_aes_192_cts(void)
{
static const EVP_CIPHER aes_192_cts = {
0,
1,
24,
16,
EVP_CIPH_CBC_MODE,
aes_cts_init,
aes_cts_do_cipher,
aes_cts_cleanup,
sizeof(AES_KEY),
NULL,
NULL,
NULL,
NULL
};
return &aes_192_cts;
}
/**
* The AES-256 cts cipher type (hcrypto)
*
* @return the AES-256 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
_hc_EVP_hcrypto_aes_256_cts(void)
{
static const EVP_CIPHER aes_256_cts = {
0,
1,
32,
16,
EVP_CIPH_CBC_MODE,
aes_cts_init,
aes_cts_do_cipher,
aes_cts_cleanup,
sizeof(AES_KEY),
NULL,
NULL,
NULL,
NULL
};
return &aes_256_cts;
}

View File

@ -0,0 +1,621 @@
/*
* Copyright (c) 2008 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* CommonCrypto provider */
#ifdef __APPLE__
#include "config.h"
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <CommonCrypto/CommonDigest.h>
#include <CommonCrypto/CommonCryptor.h>
#include <evp.h>
#include <evp-cc.h>
/*
*
*/
struct cc_key {
CCCryptorRef href;
};
static int
cc_do_cipher(EVP_CIPHER_CTX *ctx,
unsigned char *out,
const unsigned char *in,
unsigned int size)
{
struct cc_key *cc = ctx->cipher_data;
CCCryptorStatus ret;
size_t moved;
memcpy(out, in, size);
ret = CCCryptorUpdate(cc->href, in, size, out, size, &moved);
if (ret)
return 0;
if (moved != size)
return 0;
return 1;
}
static int
cc_cleanup(EVP_CIPHER_CTX *ctx)
{
struct cc_key *cc = ctx->cipher_data;
if (cc->href)
CCCryptorRelease(cc->href);
return 1;
}
static int
init_cc_key(int encp, CCAlgorithm alg, const void *key,
size_t keylen, const void *iv, CCCryptorRef *ref)
{
CCOperation op = encp ? kCCEncrypt : kCCDecrypt;
CCCryptorStatus ret;
if (*ref) {
if (key == NULL && iv) {
CCCryptorReset(*ref, iv);
return 1;
}
CCCryptorRelease(*ref);
}
ret = CCCryptorCreate(op, alg, 0, key, keylen, iv, ref);
if (ret)
return 0;
return 1;
}
static int
cc_des_ede3_cbc_init(EVP_CIPHER_CTX *ctx,
const unsigned char * key,
const unsigned char * iv,
int encp)
{
struct cc_key *cc = ctx->cipher_data;
return init_cc_key(encp, kCCAlgorithm3DES, key, kCCKeySize3DES, iv, &cc->href);
}
/**
* The tripple DES cipher type (Apple CommonCrypto provider)
*
* @return the DES-EDE3-CBC EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_cc_des_ede3_cbc(void)
{
static const EVP_CIPHER des_ede3_cbc = {
0,
8,
24,
8,
EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
cc_des_ede3_cbc_init,
cc_do_cipher,
cc_cleanup,
sizeof(struct cc_key),
NULL,
NULL,
NULL,
NULL
};
return &des_ede3_cbc;
}
/*
*
*/
static int
cc_des_cbc_init(EVP_CIPHER_CTX *ctx,
const unsigned char * key,
const unsigned char * iv,
int encp)
{
struct cc_key *cc = ctx->cipher_data;
return init_cc_key(encp, kCCAlgorithmDES, key, kCCBlockSizeDES, iv, &cc->href);
}
/**
* The DES cipher type (Apple CommonCrypto provider)
*
* @return the DES-CBC EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_cc_des_cbc(void)
{
static const EVP_CIPHER des_ede3_cbc = {
0,
kCCBlockSizeDES,
kCCBlockSizeDES,
kCCBlockSizeDES,
EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
cc_des_cbc_init,
cc_do_cipher,
cc_cleanup,
sizeof(struct cc_key),
NULL,
NULL,
NULL,
NULL
};
return &des_ede3_cbc;
}
/*
*
*/
static int
cc_aes_cbc_init(EVP_CIPHER_CTX *ctx,
const unsigned char * key,
const unsigned char * iv,
int encp)
{
struct cc_key *cc = ctx->cipher_data;
return init_cc_key(encp, kCCAlgorithmAES128, key, ctx->cipher->key_len, iv, &cc->href);
}
/**
* The AES-128 cipher type (Apple CommonCrypto provider)
*
* @return the AES-128-CBC EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_cc_aes_128_cbc(void)
{
static const EVP_CIPHER c = {
0,
kCCBlockSizeAES128,
kCCKeySizeAES128,
kCCBlockSizeAES128,
EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
cc_aes_cbc_init,
cc_do_cipher,
cc_cleanup,
sizeof(struct cc_key),
NULL,
NULL,
NULL,
NULL
};
return &c;
}
/**
* The AES-192 cipher type (Apple CommonCrypto provider)
*
* @return the AES-192-CBC EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_cc_aes_192_cbc(void)
{
static const EVP_CIPHER c = {
0,
kCCBlockSizeAES128,
kCCKeySizeAES192,
kCCBlockSizeAES128,
EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
cc_aes_cbc_init,
cc_do_cipher,
cc_cleanup,
sizeof(struct cc_key),
NULL,
NULL,
NULL,
NULL
};
return &c;
}
/**
* The AES-256 cipher type (Apple CommonCrypto provider)
*
* @return the AES-256-CBC EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_cc_aes_256_cbc(void)
{
static const EVP_CIPHER c = {
0,
kCCBlockSizeAES128,
kCCKeySizeAES256,
kCCBlockSizeAES128,
EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
cc_aes_cbc_init,
cc_do_cipher,
cc_cleanup,
sizeof(struct cc_key),
NULL,
NULL,
NULL,
NULL
};
return &c;
}
/*
*
*/
static int
cc_rc2_cbc_init(EVP_CIPHER_CTX *ctx,
const unsigned char * key,
const unsigned char * iv,
int encp)
{
struct cc_key *cc = ctx->cipher_data;
return init_cc_key(encp, kCCAlgorithmRC2, key, ctx->cipher->key_len, iv, &cc->href);
}
/**
* The RC2 cipher type - common crypto
*
* @return the RC2 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_cc_rc2_cbc(void)
{
static const EVP_CIPHER rc2_cbc = {
0,
kCCBlockSizeRC2,
16,
kCCBlockSizeRC2,
EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
cc_rc2_cbc_init,
cc_do_cipher,
cc_cleanup,
sizeof(struct cc_key),
NULL,
NULL,
NULL,
NULL
};
return &rc2_cbc;
}
/**
* The RC2-40 cipher type - common crypto
*
* @return the RC2-40 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_cc_rc2_40_cbc(void)
{
static const EVP_CIPHER rc2_40_cbc = {
0,
kCCBlockSizeRC2,
5,
kCCBlockSizeRC2,
EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
cc_rc2_cbc_init,
cc_do_cipher,
cc_cleanup,
sizeof(struct cc_key),
NULL,
NULL,
NULL,
NULL
};
return &rc2_40_cbc;
}
/**
* The RC2-64 cipher type - common crypto
*
* @return the RC2-64 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_cc_rc2_64_cbc(void)
{
static const EVP_CIPHER rc2_64_cbc = {
0,
kCCBlockSizeRC2,
8,
kCCBlockSizeRC2,
EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
cc_rc2_cbc_init,
cc_do_cipher,
cc_cleanup,
sizeof(struct cc_key),
NULL,
NULL,
NULL,
NULL
};
return &rc2_64_cbc;
}
/**
* The CommonCrypto md2 provider
*
* @ingroup hcrypto_evp
*/
const EVP_MD *
EVP_cc_md2(void)
{
static const struct hc_evp_md md2 = {
CC_MD2_DIGEST_LENGTH,
CC_MD2_BLOCK_BYTES,
sizeof(CC_MD2_CTX),
(hc_evp_md_init)CC_MD2_Init,
(hc_evp_md_update)CC_MD2_Update,
(hc_evp_md_final)CC_MD2_Final,
(hc_evp_md_cleanup)NULL
};
return &md2;
}
/**
* The CommonCrypto md4 provider
*
* @ingroup hcrypto_evp
*/
const EVP_MD *
EVP_cc_md4(void)
{
static const struct hc_evp_md md4 = {
CC_MD4_DIGEST_LENGTH,
CC_MD4_BLOCK_BYTES,
sizeof(CC_MD4_CTX),
(hc_evp_md_init)CC_MD4_Init,
(hc_evp_md_update)CC_MD4_Update,
(hc_evp_md_final)CC_MD4_Final,
(hc_evp_md_cleanup)NULL
};
return &md4;
}
/**
* The CommonCrypto md5 provider
*
* @ingroup hcrypto_evp
*/
const EVP_MD *
EVP_cc_md5(void)
{
static const struct hc_evp_md md5 = {
CC_MD5_DIGEST_LENGTH,
CC_MD5_BLOCK_BYTES,
sizeof(CC_MD5_CTX),
(hc_evp_md_init)CC_MD5_Init,
(hc_evp_md_update)CC_MD5_Update,
(hc_evp_md_final)CC_MD5_Final,
(hc_evp_md_cleanup)NULL
};
return &md5;
}
/**
* The CommonCrypto sha1 provider
*
* @ingroup hcrypto_evp
*/
const EVP_MD *
EVP_cc_sha1(void)
{
static const struct hc_evp_md sha1 = {
CC_SHA1_DIGEST_LENGTH,
CC_SHA1_BLOCK_BYTES,
sizeof(CC_SHA1_CTX),
(hc_evp_md_init)CC_SHA1_Init,
(hc_evp_md_update)CC_SHA1_Update,
(hc_evp_md_final)CC_SHA1_Final,
(hc_evp_md_cleanup)NULL
};
return &sha1;
}
/**
* The CommonCrypto sha256 provider
*
* @ingroup hcrypto_evp
*/
const EVP_MD *
EVP_cc_sha256(void)
{
static const struct hc_evp_md sha256 = {
CC_SHA256_DIGEST_LENGTH,
CC_SHA256_BLOCK_BYTES,
sizeof(CC_SHA256_CTX),
(hc_evp_md_init)CC_SHA256_Init,
(hc_evp_md_update)CC_SHA256_Update,
(hc_evp_md_final)CC_SHA256_Final,
(hc_evp_md_cleanup)NULL
};
return &sha256;
}
/**
* The Camellia-128 cipher type - CommonCrypto
*
* @return the Camellia-128 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_cc_camellia_128_cbc(void)
{
return NULL;
}
/**
* The Camellia-198 cipher type - CommonCrypto
*
* @return the Camellia-198 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_cc_camellia_192_cbc(void)
{
return NULL;
}
/**
* The Camellia-256 cipher type - CommonCrypto
*
* @return the Camellia-256 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_cc_camellia_256_cbc(void)
{
return NULL;
}
/*
*
*/
static int
cc_rc4_init(EVP_CIPHER_CTX *ctx,
const unsigned char * key,
const unsigned char * iv,
int encp)
{
struct cc_key *cc = ctx->cipher_data;
return init_cc_key(encp, kCCAlgorithmRC4, key, ctx->key_len, iv, &cc->href);
}
/**
* The RC4 cipher type (Apple CommonCrypto provider)
*
* @return the RC4 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_cc_rc4(void)
{
static const EVP_CIPHER rc4 = {
0,
1,
16,
0,
EVP_CIPH_STREAM_CIPHER|EVP_CIPH_VARIABLE_LENGTH,
cc_rc4_init,
cc_do_cipher,
cc_cleanup,
sizeof(struct cc_key),
NULL,
NULL,
NULL,
NULL
};
return &rc4;
}
/**
* The RC4-40 cipher type (Apple CommonCrypto provider)
*
* @return the RC4 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_cc_rc4_40(void)
{
static const EVP_CIPHER rc4_40 = {
0,
1,
5,
0,
EVP_CIPH_STREAM_CIPHER|EVP_CIPH_VARIABLE_LENGTH,
cc_rc4_init,
cc_do_cipher,
cc_cleanup,
sizeof(struct cc_key),
NULL,
NULL,
NULL,
NULL
};
return &rc4_40;
}
#endif /* __APPLE__ */

View File

@ -0,0 +1,91 @@
/*
* Copyright (c) 2009 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* $Id$ */
#ifndef HEIM_EVP_CC_H
#define HEIM_EVP_CC_H 1
/* symbol renaming */
#define EVP_cc_md2 hc_EVP_cc_md2
#define EVP_cc_md4 hc_EVP_cc_md4
#define EVP_cc_md5 hc_EVP_cc_md5
#define EVP_cc_sha1 hc_EVP_cc_sha1
#define EVP_cc_sha256 hc_EVP__cc_sha256
#define EVP_cc_des_cbc hc_EVP_cc_des_cbc
#define EVP_cc_des_ede3_cbc hc_EVP_cc_des_ede3_cbc
#define EVP_cc_aes_128_cbc hc_EVP_cc_aes_128_cbc
#define EVP_cc_aes_192_cbc hc_EVP_cc_aes_192_cbc
#define EVP_cc_aes_256_cbc hc_EVP_cc_aes_256_cbc
#define EVP_cc_rc4 hc_EVP_cc_rc4
#define EVP_cc_rc4_40 hc_EVP_cc_rc4_40
#define EVP_cc_rc2_40_cbc hc_EVP_cc_rc2_40_cbc
#define EVP_cc_rc2_64_cbc hc_EVP_cc_rc2_64_cbc
#define EVP_cc_rc2_cbc hc_EVP_cc_rc2_cbc
#define EVP_cc_camellia_128_cbc hc_EVP_cc_camellia_128_cbc
#define EVP_cc_camellia_192_cbc hc_EVP_cc_camellia_192_cbc
#define EVP_cc_camellia_256_cbc hc_EVP_cc_camellia_256_cbc
/*
*
*/
HC_CPP_BEGIN
const EVP_MD * EVP_cc_md2(void);
const EVP_MD * EVP_cc_md4(void);
const EVP_MD * EVP_cc_md5(void);
const EVP_MD * EVP_cc_sha1(void);
const EVP_MD * EVP_cc_sha256(void);
const EVP_CIPHER * EVP_cc_rc2_cbc(void);
const EVP_CIPHER * EVP_cc_rc2_40_cbc(void);
const EVP_CIPHER * EVP_cc_rc2_64_cbc(void);
const EVP_CIPHER * EVP_cc_rc4(void);
const EVP_CIPHER * EVP_cc_rc4_40(void);
const EVP_CIPHER * EVP_cc_des_cbc(void);
const EVP_CIPHER * EVP_cc_des_ede3_cbc(void);
const EVP_CIPHER * EVP_cc_aes_128_cbc(void);
const EVP_CIPHER * EVP_cc_aes_192_cbc(void);
const EVP_CIPHER * EVP_cc_aes_256_cbc(void);
const EVP_CIPHER * EVP_cc_camellia_128_cbc(void);
const EVP_CIPHER * EVP_cc_camellia_192_cbc(void);
const EVP_CIPHER * EVP_cc_camellia_256_cbc(void);
HC_CPP_END
#endif /* HEIM_EVP_CC_H */

View File

@ -42,11 +42,22 @@
#include <assert.h>
#include <evp.h>
#include <evp-hcrypto.h>
#include <krb5-types.h>
#include <des.h>
#include "camellia.h"
#include <aes.h>
#include <rc2.h>
#include <rc4.h>
#include <sha.h>
#include <md2.h>
#include <md4.h>
#include <md5.h>
/*
*
*/
@ -76,13 +87,6 @@ aes_do_cipher(EVP_CIPHER_CTX *ctx,
return 1;
}
static int
aes_cleanup(EVP_CIPHER_CTX *ctx)
{
memset(ctx->cipher_data, 0, sizeof(AES_KEY));
return 1;
}
/**
* The AES-128 cipher type (hcrypto)
*
@ -102,7 +106,7 @@ EVP_hcrypto_aes_128_cbc(void)
EVP_CIPH_CBC_MODE,
aes_init,
aes_do_cipher,
aes_cleanup,
NULL,
sizeof(AES_KEY),
NULL,
NULL,
@ -132,7 +136,7 @@ EVP_hcrypto_aes_192_cbc(void)
EVP_CIPH_CBC_MODE,
aes_init,
aes_do_cipher,
aes_cleanup,
NULL,
sizeof(AES_KEY),
NULL,
NULL,
@ -161,7 +165,7 @@ EVP_hcrypto_aes_256_cbc(void)
EVP_CIPH_CBC_MODE,
aes_init,
aes_do_cipher,
aes_cleanup,
NULL,
sizeof(AES_KEY),
NULL,
NULL,
@ -170,3 +174,547 @@ EVP_hcrypto_aes_256_cbc(void)
};
return &aes_256_cbc;
}
/**
* The message digest SHA256 - hcrypto
*
* @return the message digest type.
*
* @ingroup hcrypto_evp
*/
const EVP_MD *
EVP_hcrypto_sha256(void)
{
static const struct hc_evp_md sha256 = {
32,
64,
sizeof(SHA256_CTX),
(hc_evp_md_init)SHA256_Init,
(hc_evp_md_update)SHA256_Update,
(hc_evp_md_final)SHA256_Final,
NULL
};
return &sha256;
}
/**
* The message digest SHA1 - hcrypto
*
* @return the message digest type.
*
* @ingroup hcrypto_evp
*/
const EVP_MD *
EVP_hcrypto_sha1(void)
{
static const struct hc_evp_md sha1 = {
20,
64,
sizeof(SHA_CTX),
(hc_evp_md_init)SHA1_Init,
(hc_evp_md_update)SHA1_Update,
(hc_evp_md_final)SHA1_Final,
NULL
};
return &sha1;
}
/**
* The message digest MD5 - hcrypto
*
* @return the message digest type.
*
* @ingroup hcrypto_evp
*/
const EVP_MD *
EVP_hcrypto_md5(void)
{
static const struct hc_evp_md md5 = {
16,
64,
sizeof(MD5_CTX),
(hc_evp_md_init)MD5_Init,
(hc_evp_md_update)MD5_Update,
(hc_evp_md_final)MD5_Final,
NULL
};
return &md5;
}
/**
* The message digest MD4 - hcrypto
*
* @return the message digest type.
*
* @ingroup hcrypto_evp
*/
const EVP_MD *
EVP_hcrypto_md4(void)
{
static const struct hc_evp_md md4 = {
16,
64,
sizeof(MD4_CTX),
(hc_evp_md_init)MD4_Init,
(hc_evp_md_update)MD4_Update,
(hc_evp_md_final)MD4_Final,
NULL
};
return &md4;
}
/**
* The message digest MD2 - hcrypto
*
* @return the message digest type.
*
* @ingroup hcrypto_evp
*/
const EVP_MD *
EVP_hcrypto_md2(void)
{
static const struct hc_evp_md md2 = {
16,
16,
sizeof(MD2_CTX),
(hc_evp_md_init)MD2_Init,
(hc_evp_md_update)MD2_Update,
(hc_evp_md_final)MD2_Final,
NULL
};
return &md2;
}
/*
*
*/
static int
des_cbc_init(EVP_CIPHER_CTX *ctx,
const unsigned char * key,
const unsigned char * iv,
int encp)
{
DES_key_schedule *k = ctx->cipher_data;
DES_cblock deskey;
memcpy(&deskey, key, sizeof(deskey));
DES_set_key_unchecked(&deskey, k);
return 1;
}
static int
des_cbc_do_cipher(EVP_CIPHER_CTX *ctx,
unsigned char *out,
const unsigned char *in,
unsigned int size)
{
DES_key_schedule *k = ctx->cipher_data;
DES_cbc_encrypt(in, out, size,
k, (DES_cblock *)ctx->iv, ctx->encrypt);
return 1;
}
/**
* The DES cipher type
*
* @return the DES-CBC EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_hcrypto_des_cbc(void)
{
static const EVP_CIPHER des_cbc = {
0,
8,
8,
8,
EVP_CIPH_CBC_MODE,
des_cbc_init,
des_cbc_do_cipher,
NULL,
sizeof(DES_key_schedule),
NULL,
NULL,
NULL,
NULL
};
return &des_cbc;
}
/*
*
*/
struct des_ede3_cbc {
DES_key_schedule ks[3];
};
static int
des_ede3_cbc_init(EVP_CIPHER_CTX *ctx,
const unsigned char * key,
const unsigned char * iv,
int encp)
{
struct des_ede3_cbc *k = ctx->cipher_data;
DES_cblock deskey;
memcpy(&deskey, key, sizeof(deskey));
DES_set_odd_parity(&deskey);
DES_set_key_unchecked(&deskey, &k->ks[0]);
memcpy(&deskey, key + 8, sizeof(deskey));
DES_set_odd_parity(&deskey);
DES_set_key_unchecked(&deskey, &k->ks[1]);
memcpy(&deskey, key + 16, sizeof(deskey));
DES_set_odd_parity(&deskey);
DES_set_key_unchecked(&deskey, &k->ks[2]);
return 1;
}
static int
des_ede3_cbc_do_cipher(EVP_CIPHER_CTX *ctx,
unsigned char *out,
const unsigned char *in,
unsigned int size)
{
struct des_ede3_cbc *k = ctx->cipher_data;
DES_ede3_cbc_encrypt(in, out, size,
&k->ks[0], &k->ks[1], &k->ks[2],
(DES_cblock *)ctx->iv, ctx->encrypt);
return 1;
}
/**
* The tripple DES cipher type - hcrypto
*
* @return the DES-EDE3-CBC EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_hcrypto_des_ede3_cbc(void)
{
static const EVP_CIPHER des_ede3_cbc = {
0,
8,
24,
8,
EVP_CIPH_CBC_MODE,
des_ede3_cbc_init,
des_ede3_cbc_do_cipher,
NULL,
sizeof(struct des_ede3_cbc),
NULL,
NULL,
NULL,
NULL
};
return &des_ede3_cbc;
}
/*
*
*/
struct rc2_cbc {
unsigned int maximum_effective_key;
RC2_KEY key;
};
static int
rc2_init(EVP_CIPHER_CTX *ctx,
const unsigned char * key,
const unsigned char * iv,
int encp)
{
struct rc2_cbc *k = ctx->cipher_data;
k->maximum_effective_key = EVP_CIPHER_CTX_key_length(ctx) * 8;
RC2_set_key(&k->key,
EVP_CIPHER_CTX_key_length(ctx),
key,
k->maximum_effective_key);
return 1;
}
static int
rc2_do_cipher(EVP_CIPHER_CTX *ctx,
unsigned char *out,
const unsigned char *in,
unsigned int size)
{
struct rc2_cbc *k = ctx->cipher_data;
RC2_cbc_encrypt(in, out, size, &k->key, ctx->iv, ctx->encrypt);
return 1;
}
/**
* The RC2 cipher type - hcrypto
*
* @return the RC2 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_hcrypto_rc2_cbc(void)
{
static const EVP_CIPHER rc2_cbc = {
0,
RC2_BLOCK_SIZE,
RC2_KEY_LENGTH,
RC2_BLOCK_SIZE,
EVP_CIPH_CBC_MODE|EVP_CIPH_VARIABLE_LENGTH,
rc2_init,
rc2_do_cipher,
NULL,
sizeof(struct rc2_cbc),
NULL,
NULL,
NULL,
NULL
};
return &rc2_cbc;
}
/**
* The RC2-40 cipher type
*
* @return the RC2-40 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_hcrypto_rc2_40_cbc(void)
{
static const EVP_CIPHER rc2_40_cbc = {
0,
RC2_BLOCK_SIZE,
5,
RC2_BLOCK_SIZE,
EVP_CIPH_CBC_MODE,
rc2_init,
rc2_do_cipher,
NULL,
sizeof(struct rc2_cbc),
NULL,
NULL,
NULL,
NULL
};
return &rc2_40_cbc;
}
/**
* The RC2-64 cipher type
*
* @return the RC2-64 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_hcrypto_rc2_64_cbc(void)
{
static const EVP_CIPHER rc2_64_cbc = {
0,
RC2_BLOCK_SIZE,
8,
RC2_BLOCK_SIZE,
EVP_CIPH_CBC_MODE,
rc2_init,
rc2_do_cipher,
NULL,
sizeof(struct rc2_cbc),
NULL,
NULL,
NULL,
NULL
};
return &rc2_64_cbc;
}
static int
camellia_init(EVP_CIPHER_CTX *ctx,
const unsigned char * key,
const unsigned char * iv,
int encp)
{
CAMELLIA_KEY *k = ctx->cipher_data;
k->bits = ctx->cipher->key_len * 8;
CAMELLIA_set_key(key, ctx->cipher->key_len * 8, k);
return 1;
}
static int
camellia_do_cipher(EVP_CIPHER_CTX *ctx,
unsigned char *out,
const unsigned char *in,
unsigned int size)
{
CAMELLIA_KEY *k = ctx->cipher_data;
CAMELLIA_cbc_encrypt(in, out, size, k, ctx->iv, ctx->encrypt);
return 1;
}
/**
* The Camellia-128 cipher type - hcrypto
*
* @return the Camellia-128 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_hcrypto_camellia_128_cbc(void)
{
static const EVP_CIPHER cipher = {
0,
16,
16,
16,
EVP_CIPH_CBC_MODE,
camellia_init,
camellia_do_cipher,
NULL,
sizeof(CAMELLIA_KEY),
NULL,
NULL,
NULL,
NULL
};
return &cipher;
}
/**
* The Camellia-198 cipher type - hcrypto
*
* @return the Camellia-198 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_hcrypto_camellia_192_cbc(void)
{
static const EVP_CIPHER cipher = {
0,
16,
24,
16,
EVP_CIPH_CBC_MODE,
camellia_init,
camellia_do_cipher,
NULL,
sizeof(CAMELLIA_KEY),
NULL,
NULL,
NULL,
NULL
};
return &cipher;
}
/**
* The Camellia-256 cipher type - hcrypto
*
* @return the Camellia-256 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_hcrypto_camellia_256_cbc(void)
{
static const EVP_CIPHER cipher = {
0,
16,
32,
16,
EVP_CIPH_CBC_MODE,
camellia_init,
camellia_do_cipher,
NULL,
sizeof(CAMELLIA_KEY),
NULL,
NULL,
NULL,
NULL
};
return &cipher;
}
static int
rc4_init(EVP_CIPHER_CTX *ctx,
const unsigned char *key,
const unsigned char *iv,
int enc)
{
RC4_KEY *k = ctx->cipher_data;
RC4_set_key(k, ctx->key_len, key);
return 1;
}
static int
rc4_do_cipher(EVP_CIPHER_CTX *ctx,
unsigned char *out,
const unsigned char *in,
unsigned int size)
{
RC4_KEY *k = ctx->cipher_data;
RC4(k, size, in, out);
return 1;
}
const EVP_CIPHER *
EVP_hcrypto_rc4(void)
{
static const EVP_CIPHER rc4 = {
0,
1,
16,
0,
EVP_CIPH_STREAM_CIPHER|EVP_CIPH_VARIABLE_LENGTH,
rc4_init,
rc4_do_cipher,
NULL,
sizeof(RC4_KEY),
NULL,
NULL,
NULL,
NULL
};
return &rc4;
}
const EVP_CIPHER *
EVP_hcrypto_rc4_40(void)
{
static const EVP_CIPHER rc4_40 = {
0,
1,
5,
0,
EVP_CIPH_STREAM_CIPHER|EVP_CIPH_VARIABLE_LENGTH,
rc4_init,
rc4_do_cipher,
NULL,
sizeof(RC4_KEY),
NULL,
NULL,
NULL,
NULL
};
return &rc4_40;
}

View File

@ -0,0 +1,92 @@
/*
* Copyright (c) 2009 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* $Id$ */
#ifndef HEIM_EVP_HCRYPTO_H
#define HEIM_EVP_HCRYPTO_H 1
/* symbol renaming */
#define EVP_hcrypto_md2 hc_EVP_hcrypto_md2
#define EVP_hcrypto_md4 hc_EVP_hcrypto_md4
#define EVP_hcrypto_md5 hc_EVP_hcrypto_md5
#define EVP_hcrypto_sha1 hc_EVP_hcrypto_sha1
#define EVP_hcrypto_sha256 hc_EVP_hcrypto_sha256
#define EVP_hcrypto_des_cbc hc_EVP_hcrypto_des_cbc
#define EVP_hcrypto_des_ede3_cbc hc_EVP_hcrypto_des_ede3_cbc
#define EVP_hcrypto_aes_128_cbc hc_EVP_hcrypto_aes_128_cbc
#define EVP_hcrypto_aes_192_cbc hc_EVP_hcrypto_aes_192_cbc
#define EVP_hcrypto_aes_256_cbc hc_EVP_hcrypto_aes_256_cbc
#define EVP_hcrypto_rc4 hc_EVP_hcrypto_rc4
#define EVP_hcrypto_rc4_40 hc_EVP_hcrypto_rc4_40
#define EVP_hcrypto_rc2_40_cbc hc_EVP_hcrypto_rc2_40_cbc
#define EVP_hcrypto_rc2_64_cbc hc_EVP_hcrypto_rc2_64_cbc
#define EVP_hcrypto_rc2_cbc hc_EVP_hcrypto_rc2_cbc
#define EVP_hcrypto_camellia_128_cbc hc_EVP_hcrypto_camellia_128_cbc
#define EVP_hcrypto_camellia_192_cbc hc_EVP_hcrypto_camellia_192_cbc
#define EVP_hcrypto_camellia_256_cbc hc_EVP_hcrypto_camellia_256_cbc
/*
*
*/
HC_CPP_BEGIN
const EVP_MD * EVP_hcrypto_md2(void);
const EVP_MD * EVP_hcrypto_md4(void);
const EVP_MD * EVP_hcrypto_md5(void);
const EVP_MD * EVP_hcrypto_sha1(void);
const EVP_MD * EVP_hcrypto_sha256(void);
const EVP_CIPHER * EVP_hcrypto_rc4(void);
const EVP_CIPHER * EVP_hcrypto_rc4_40(void);
const EVP_CIPHER * EVP_hcrypto_rc2_cbc(void);
const EVP_CIPHER * EVP_hcrypto_rc2_40_cbc(void);
const EVP_CIPHER * EVP_hcrypto_rc2_64_cbc(void);
const EVP_CIPHER * EVP_hcrypto_des_cbc(void);
const EVP_CIPHER * EVP_hcrypto_des_ede3_cbc(void);
const EVP_CIPHER * EVP_hcrypto_aes_128_cbc(void);
const EVP_CIPHER * EVP_hcrypto_aes_192_cbc(void);
const EVP_CIPHER * EVP_hcrypto_aes_256_cbc(void);
const EVP_CIPHER * EVP_hcrypto_camellia_128_cbc(void);
const EVP_CIPHER * EVP_hcrypto_camellia_192_cbc(void);
const EVP_CIPHER * EVP_hcrypto_camellia_256_cbc(void);
HC_CPP_END
#endif /* HEIM_EVP_HCRYPTO_H */

View File

@ -45,17 +45,19 @@
#include <assert.h>
#include <evp.h>
#include <evp-hcrypto.h>
#include <evp-cc.h>
#include <krb5-types.h>
#include "camellia.h"
#include <des.h>
#include <sha.h>
#include <rc2.h>
#include <rc4.h>
#include <md2.h>
#include <md4.h>
#include <md5.h>
#ifndef HCRYPTO_DEF_PROVIDER
#define HCRYPTO_DEF_PROVIDER hcrypto
#endif
#define HC_CONCAT4(x,y,z,aa) x ## y ## z ## aa
#define EVP_DEF_OP(_prov,_op) HC_CONCAT4(EVP_,_prov,_,_op)()
/**
* @page page_evp EVP - generic crypto interface
@ -138,8 +140,8 @@ EVP_MD_CTX_create(void)
* @ingroup hcrypto_evp
*/
void HC_DEPRECATED
EVP_MD_CTX_init(EVP_MD_CTX *ctx)
void
EVP_MD_CTX_init(EVP_MD_CTX *ctx) HC_DEPRECATED
{
memset(ctx, 0, sizeof(*ctx));
}
@ -169,11 +171,13 @@ EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
* @ingroup hcrypto_evp
*/
int HC_DEPRECATED
EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
int
EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) HC_DEPRECATED
{
if (ctx->md && ctx->md->cleanup)
(ctx->md->cleanup)(ctx);
else if (ctx->md)
memset(ctx->ptr, 0, ctx->md->ctx_size);
ctx->md = NULL;
ctx->engine = NULL;
free(ctx->ptr);
@ -351,28 +355,9 @@ EVP_Digest(const void *data, size_t dsize, void *hash, unsigned int *hsize,
const EVP_MD *
EVP_sha256(void)
{
static const struct hc_evp_md sha256 = {
32,
64,
sizeof(SHA256_CTX),
(hc_evp_md_init)SHA256_Init,
(hc_evp_md_update)SHA256_Update,
(hc_evp_md_final)SHA256_Final,
NULL
};
return &sha256;
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, sha256);
}
static const struct hc_evp_md sha1 = {
20,
64,
sizeof(SHA_CTX),
(hc_evp_md_init)SHA1_Init,
(hc_evp_md_update)SHA1_Update,
(hc_evp_md_final)SHA1_Final,
NULL
};
/**
* The message digest SHA1
*
@ -384,7 +369,7 @@ static const struct hc_evp_md sha1 = {
const EVP_MD *
EVP_sha1(void)
{
return &sha1;
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, sha1);
}
/**
@ -396,9 +381,10 @@ EVP_sha1(void)
*/
const EVP_MD *
EVP_sha(void)
EVP_sha(void) HC_DEPRECATED
{
return &sha1;
return EVP_sha1();
}
/**
@ -410,18 +396,9 @@ EVP_sha(void)
*/
const EVP_MD *
EVP_md5(void)
EVP_md5(void) HC_DEPRECATED_CRYPTO
{
static const struct hc_evp_md md5 = {
16,
64,
sizeof(MD5_CTX),
(hc_evp_md_init)MD5_Init,
(hc_evp_md_update)MD5_Update,
(hc_evp_md_final)MD5_Final,
NULL
};
return &md5;
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, md5);
}
/**
@ -433,18 +410,9 @@ EVP_md5(void)
*/
const EVP_MD *
EVP_md4(void)
EVP_md4(void) HC_DEPRECATED_CRYPTO
{
static const struct hc_evp_md md4 = {
16,
64,
sizeof(MD4_CTX),
(hc_evp_md_init)MD4_Init,
(hc_evp_md_update)MD4_Update,
(hc_evp_md_final)MD4_Final,
NULL
};
return &md4;
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, md4);
}
/**
@ -456,18 +424,9 @@ EVP_md4(void)
*/
const EVP_MD *
EVP_md2(void)
EVP_md2(void) HC_DEPRECATED_CRYPTO
{
static const struct hc_evp_md md2 = {
16,
16,
sizeof(MD2_CTX),
(hc_evp_md_init)MD2_Init,
(hc_evp_md_update)MD2_Update,
(hc_evp_md_final)MD2_Final,
NULL
};
return &md2;
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, md2);
}
/*
@ -589,19 +548,35 @@ EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
if (c->cipher && c->cipher->cleanup)
c->cipher->cleanup(c);
if (c->cipher_data) {
memset(c->cipher_data, 0, c->cipher->ctx_size);
free(c->cipher_data);
c->cipher_data = NULL;
}
return 1;
}
#if 0
/**
* If the cipher type supports it, change the key length
*
* @param c the cipher context to change the key length for
* @param length new key length
*
* @return 1 on success.
*
* @ingroup hcrypto_evp
*/
int
EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int length)
{
if ((c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH) && length > 0) {
c->key_len = length;
return 1;
}
return 0;
}
#if 0
int
EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad)
{
@ -768,7 +743,7 @@ EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *c, ENGINE *engine,
ctx->cipher = c;
ctx->key_len = c->key_len;
ctx->cipher_data = malloc(c->ctx_size);
ctx->cipher_data = calloc(1, c->ctx_size);
if (ctx->cipher_data == NULL && c->ctx_size != 0)
return 0;
@ -780,7 +755,7 @@ EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *c, ENGINE *engine,
return 0;
}
switch (EVP_CIPHER_CTX_flags(ctx)) {
switch (EVP_CIPHER_CTX_mode(ctx)) {
case EVP_CIPH_CBC_MODE:
assert(EVP_CIPHER_CTX_iv_length(ctx) <= sizeof(ctx->iv));
@ -789,6 +764,10 @@ EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *c, ENGINE *engine,
memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
break;
case EVP_CIPH_STREAM_CIPHER:
break;
default:
return 0;
}
@ -1005,48 +984,6 @@ EVP_enc_null(void)
return &enc_null;
}
/*
*
*/
struct rc2_cbc {
unsigned int maximum_effective_key;
RC2_KEY key;
};
static int
rc2_init(EVP_CIPHER_CTX *ctx,
const unsigned char * key,
const unsigned char * iv,
int encp)
{
struct rc2_cbc *k = ctx->cipher_data;
k->maximum_effective_key = EVP_CIPHER_CTX_key_length(ctx) * 8;
RC2_set_key(&k->key,
EVP_CIPHER_CTX_key_length(ctx),
key,
k->maximum_effective_key);
return 1;
}
static int
rc2_do_cipher(EVP_CIPHER_CTX *ctx,
unsigned char *out,
const unsigned char *in,
unsigned int size)
{
struct rc2_cbc *k = ctx->cipher_data;
RC2_cbc_encrypt(in, out, size, &k->key, ctx->iv, ctx->encrypt);
return 1;
}
static int
rc2_cleanup(EVP_CIPHER_CTX *ctx)
{
memset(ctx->cipher_data, 0, sizeof(struct rc2_cbc));
return 1;
}
/**
* The RC2 cipher type
*
@ -1058,28 +995,13 @@ rc2_cleanup(EVP_CIPHER_CTX *ctx)
const EVP_CIPHER *
EVP_rc2_cbc(void)
{
static const EVP_CIPHER rc2_cbc = {
0,
RC2_BLOCK_SIZE,
RC2_KEY_LENGTH,
RC2_BLOCK_SIZE,
EVP_CIPH_CBC_MODE,
rc2_init,
rc2_do_cipher,
rc2_cleanup,
sizeof(struct rc2_cbc),
NULL,
NULL,
NULL,
NULL
};
return &rc2_cbc;
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, rc2_cbc);
}
/**
* The RC2-40 cipher type
* The RC2 cipher type
*
* @return the RC2-40 EVP_CIPHER pointer.
* @return the RC2 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
@ -1087,28 +1009,13 @@ EVP_rc2_cbc(void)
const EVP_CIPHER *
EVP_rc2_40_cbc(void)
{
static const EVP_CIPHER rc2_40_cbc = {
0,
RC2_BLOCK_SIZE,
5,
RC2_BLOCK_SIZE,
EVP_CIPH_CBC_MODE,
rc2_init,
rc2_do_cipher,
rc2_cleanup,
sizeof(struct rc2_cbc),
NULL,
NULL,
NULL,
NULL
};
return &rc2_40_cbc;
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, rc2_40_cbc);
}
/**
* The RC2-64 cipher type
* The RC2 cipher type
*
* @return the RC2-64 EVP_CIPHER pointer.
* @return the RC2 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
@ -1116,22 +1023,7 @@ EVP_rc2_40_cbc(void)
const EVP_CIPHER *
EVP_rc2_64_cbc(void)
{
static const EVP_CIPHER rc2_64_cbc = {
0,
RC2_BLOCK_SIZE,
8,
RC2_BLOCK_SIZE,
EVP_CIPH_CBC_MODE,
rc2_init,
rc2_do_cipher,
rc2_cleanup,
sizeof(struct rc2_cbc),
NULL,
NULL,
NULL,
NULL
};
return &rc2_64_cbc;
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, rc2_64_cbc);
}
/**
@ -1145,9 +1037,7 @@ EVP_rc2_64_cbc(void)
const EVP_CIPHER *
EVP_rc4(void)
{
printf("evp rc4\n");
abort();
return NULL;
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, rc4);
}
/**
@ -1161,45 +1051,7 @@ EVP_rc4(void)
const EVP_CIPHER *
EVP_rc4_40(void)
{
printf("evp rc4_40\n");
abort();
return NULL;
}
/*
*
*/
static int
des_cbc_init(EVP_CIPHER_CTX *ctx,
const unsigned char * key,
const unsigned char * iv,
int encp)
{
DES_key_schedule *k = ctx->cipher_data;
DES_cblock deskey;
memcpy(&deskey, key, sizeof(deskey));
DES_set_key_unchecked(&deskey, k);
return 1;
}
static int
des_cbc_do_cipher(EVP_CIPHER_CTX *ctx,
unsigned char *out,
const unsigned char *in,
unsigned int size)
{
DES_key_schedule *k = ctx->cipher_data;
DES_cbc_encrypt(in, out, size,
k, (DES_cblock *)ctx->iv, ctx->encrypt);
return 1;
}
static int
des_cbc_cleanup(EVP_CIPHER_CTX *ctx)
{
memset(ctx->cipher_data, 0, sizeof(struct DES_key_schedule));
return 1;
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, rc4_40);
}
/**
@ -1213,74 +1065,7 @@ des_cbc_cleanup(EVP_CIPHER_CTX *ctx)
const EVP_CIPHER *
EVP_des_cbc(void)
{
static const EVP_CIPHER des_ede3_cbc = {
0,
8,
8,
8,
EVP_CIPH_CBC_MODE,
des_cbc_init,
des_cbc_do_cipher,
des_cbc_cleanup,
sizeof(DES_key_schedule),
NULL,
NULL,
NULL,
NULL
};
return &des_ede3_cbc;
}
/*
*
*/
struct des_ede3_cbc {
DES_key_schedule ks[3];
};
static int
des_ede3_cbc_init(EVP_CIPHER_CTX *ctx,
const unsigned char * key,
const unsigned char * iv,
int encp)
{
struct des_ede3_cbc *k = ctx->cipher_data;
DES_cblock deskey;
memcpy(&deskey, key, sizeof(deskey));
DES_set_odd_parity(&deskey);
DES_set_key_unchecked(&deskey, &k->ks[0]);
memcpy(&deskey, key + 8, sizeof(deskey));
DES_set_odd_parity(&deskey);
DES_set_key_unchecked(&deskey, &k->ks[1]);
memcpy(&deskey, key + 16, sizeof(deskey));
DES_set_odd_parity(&deskey);
DES_set_key_unchecked(&deskey, &k->ks[2]);
return 1;
}
static int
des_ede3_cbc_do_cipher(EVP_CIPHER_CTX *ctx,
unsigned char *out,
const unsigned char *in,
unsigned int size)
{
struct des_ede3_cbc *k = ctx->cipher_data;
DES_ede3_cbc_encrypt(in, out, size,
&k->ks[0], &k->ks[1], &k->ks[2],
(DES_cblock *)ctx->iv, ctx->encrypt);
return 1;
}
static int
des_ede3_cbc_cleanup(EVP_CIPHER_CTX *ctx)
{
memset(ctx->cipher_data, 0, sizeof(struct des_ede3_cbc));
return 1;
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, des_cbc);
}
/**
@ -1294,22 +1079,7 @@ des_ede3_cbc_cleanup(EVP_CIPHER_CTX *ctx)
const EVP_CIPHER *
EVP_des_ede3_cbc(void)
{
static const EVP_CIPHER des_ede3_cbc = {
0,
8,
24,
8,
EVP_CIPH_CBC_MODE,
des_ede3_cbc_init,
des_ede3_cbc_do_cipher,
des_ede3_cbc_cleanup,
sizeof(struct des_ede3_cbc),
NULL,
NULL,
NULL,
NULL
};
return &des_ede3_cbc;
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, des_ede3_cbc);
}
/**
@ -1323,7 +1093,7 @@ EVP_des_ede3_cbc(void)
const EVP_CIPHER *
EVP_aes_128_cbc(void)
{
return EVP_hcrypto_aes_128_cbc();
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, aes_128_cbc);
}
/**
@ -1337,7 +1107,7 @@ EVP_aes_128_cbc(void)
const EVP_CIPHER *
EVP_aes_192_cbc(void)
{
return EVP_hcrypto_aes_192_cbc();
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, aes_192_cbc);
}
/**
@ -1351,37 +1121,7 @@ EVP_aes_192_cbc(void)
const EVP_CIPHER *
EVP_aes_256_cbc(void)
{
return EVP_hcrypto_aes_256_cbc();
}
static int
camellia_init(EVP_CIPHER_CTX *ctx,
const unsigned char * key,
const unsigned char * iv,
int encp)
{
CAMELLIA_KEY *k = ctx->cipher_data;
k->bits = ctx->cipher->key_len * 8;
CAMELLIA_set_key(key, ctx->cipher->key_len * 8, k);
return 1;
}
static int
camellia_do_cipher(EVP_CIPHER_CTX *ctx,
unsigned char *out,
const unsigned char *in,
unsigned int size)
{
CAMELLIA_KEY *k = ctx->cipher_data;
CAMELLIA_cbc_encrypt(in, out, size, k, ctx->iv, ctx->encrypt);
return 1;
}
static int
camellia_cleanup(EVP_CIPHER_CTX *ctx)
{
memset(ctx->cipher_data, 0, sizeof(CAMELLIA_KEY));
return 1;
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, aes_256_cbc);
}
/**
@ -1395,22 +1135,7 @@ camellia_cleanup(EVP_CIPHER_CTX *ctx)
const EVP_CIPHER *
EVP_camellia_128_cbc(void)
{
static const EVP_CIPHER cipher = {
0,
16,
16,
16,
EVP_CIPH_CBC_MODE,
camellia_init,
camellia_do_cipher,
camellia_cleanup,
sizeof(CAMELLIA_KEY),
NULL,
NULL,
NULL,
NULL
};
return &cipher;
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, camellia_128_cbc);
}
/**
@ -1424,22 +1149,7 @@ EVP_camellia_128_cbc(void)
const EVP_CIPHER *
EVP_camellia_192_cbc(void)
{
static const EVP_CIPHER cipher = {
0,
16,
24,
16,
EVP_CIPH_CBC_MODE,
camellia_init,
camellia_do_cipher,
camellia_cleanup,
sizeof(CAMELLIA_KEY),
NULL,
NULL,
NULL,
NULL
};
return &cipher;
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, camellia_192_cbc);
}
/**
@ -1453,22 +1163,7 @@ EVP_camellia_192_cbc(void)
const EVP_CIPHER *
EVP_camellia_256_cbc(void)
{
static const EVP_CIPHER cipher = {
0,
16,
32,
16,
EVP_CIPH_CBC_MODE,
camellia_init,
camellia_do_cipher,
camellia_cleanup,
sizeof(CAMELLIA_KEY),
NULL,
NULL,
NULL,
NULL
};
return &cipher;
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, camellia_256_cbc);
}
/*

View File

@ -74,12 +74,7 @@
#define EVP_aes_128_cbc hc_EVP_aes_128_cbc
#define EVP_aes_192_cbc hc_EVP_aes_192_cbc
#define EVP_aes_256_cbc hc_EVP_aes_256_cbc
#define EVP_hcrypto_aes_128_cbc hc_EVP_hcrypto_aes_128_cbc
#define EVP_hcrypto_aes_192_cbc hc_EVP_hcrypto_aes_192_cbc
#define EVP_hcrypto_aes_256_cbc hc_EVP_hcrypto_aes_256_cbc
#define EVP_hcrypto_aes_128_cts hc_EVP_hcrypto_aes_128_cts
#define EVP_hcrypto_aes_192_cts hc_EVP_hcrypto_aes_192_cts
#define EVP_hcrypto_aes_256_cts hc_EVP_hcrypto_aes_256_cts
#define EVP_des_cbc hc_EVP_des_cbc
#define EVP_des_ede3_cbc hc_EVP_des_ede3_cbc
#define EVP_enc_null hc_EVP_enc_null
@ -136,6 +131,7 @@ struct hc_CIPHER {
#define EVP_CIPH_CBC_MODE 2
#define EVP_CIPH_MODE 0x7
#define EVP_CIPH_VARIABLE_LENGTH 0x008 /* variable key length */
#define EVP_CIPH_ALWAYS_CALL_INIT 0x020
#define EVP_CIPH_RAND_KEY 0x200
@ -203,11 +199,16 @@ struct hc_evp_md {
#define HC_DEPRECATED_CRYPTO HC_DEPRECATED
#endif
#ifdef __cplusplus
extern "C" {
#ifdef __cplusplus
#define HC_CPP_BEGIN extern "C" {
#define HC_CPP_END }
#else
#define HC_CPP_BEGIN
#define HC_CPP_END
#endif
HC_CPP_BEGIN
/*
* Avaible crypto algs
*/
@ -216,19 +217,13 @@ const EVP_MD *EVP_md_null(void);
const EVP_MD *EVP_md2(void) HC_DEPRECATED_CRYPTO;
const EVP_MD *EVP_md4(void) HC_DEPRECATED_CRYPTO;
const EVP_MD *EVP_md5(void) HC_DEPRECATED_CRYPTO;
const EVP_MD *EVP_sha(void);
const EVP_MD *EVP_sha(void) HC_DEPRECATED;
const EVP_MD *EVP_sha1(void);
const EVP_MD *EVP_sha256(void);
const EVP_CIPHER * EVP_aes_128_cbc(void);
const EVP_CIPHER * EVP_aes_192_cbc(void);
const EVP_CIPHER * EVP_aes_256_cbc(void);
const EVP_CIPHER * EVP_hcrypto_aes_128_cbc(void);
const EVP_CIPHER * EVP_hcrypto_aes_192_cbc(void);
const EVP_CIPHER * EVP_hcrypto_aes_256_cbc(void);
const EVP_CIPHER * EVP_hcrypto_aes_128_cts(void);
const EVP_CIPHER * EVP_hcrypto_aes_192_cts(void);
const EVP_CIPHER * EVP_hcrypto_aes_256_cts(void);
const EVP_CIPHER * EVP_des_cbc(void) HC_DEPRECATED_CRYPTO;
const EVP_CIPHER * EVP_des_ede3_cbc(void);
const EVP_CIPHER * EVP_enc_null(void);
@ -241,10 +236,6 @@ const EVP_CIPHER * EVP_camellia_128_cbc(void);
const EVP_CIPHER * EVP_camellia_192_cbc(void);
const EVP_CIPHER * EVP_camellia_256_cbc(void);
/*
*
*/
size_t EVP_MD_size(const EVP_MD *);
size_t EVP_MD_block_size(const EVP_MD *);
@ -318,8 +309,6 @@ void OpenSSL_add_all_algorithms(void);
void OpenSSL_add_all_algorithms_conf(void);
void OpenSSL_add_all_algorithms_noconf(void);
#ifdef __cplusplus
}
#endif
HC_CPP_END
#endif /* HEIM_EVP_H */

File diff suppressed because it is too large Load Diff

View File

@ -99,7 +99,7 @@ extern const mp_result MP_MINERR;
/* Values with fewer than this many significant digits use the
standard multiplication algorithm; otherwise, a recursive algorithm
is used. Choose a value to suit your platform.
is used. Choose a value to suit your platform.
*/
#define MP_MULT_THRESH 22
@ -157,14 +157,14 @@ int mp_int_is_pow2(mp_int z);
mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m,
mp_int c); /* c = a^b (mod m) */
mp_result mp_int_exptmod_evalue(mp_int a, mp_small value,
mp_result mp_int_exptmod_evalue(mp_int a, mp_small value,
mp_int m, mp_int c); /* c = a^v (mod m) */
mp_result mp_int_exptmod_bvalue(mp_small value, mp_int b,
mp_int m, mp_int c); /* c = v^b (mod m) */
mp_result mp_int_exptmod_known(mp_int a, mp_int b,
mp_int m, mp_int mu,
mp_int c); /* c = a^b (mod m) */
mp_result mp_int_redux_const(mp_int m, mp_int c);
mp_result mp_int_redux_const(mp_int m, mp_int c);
mp_result mp_int_invmod(mp_int a, mp_int m, mp_int c); /* c = 1/a (mod m) */
@ -184,16 +184,16 @@ mp_result mp_int_to_uint(mp_int z, mp_usmall *out);
/* Convert to nul-terminated string with the specified radix, writing at
most limit characters including the nul terminator */
mp_result mp_int_to_string(mp_int z, mp_size radix,
mp_result mp_int_to_string(mp_int z, mp_size radix,
char *str, int limit);
/* Return the number of characters required to represent
/* Return the number of characters required to represent
z in the given radix. May over-estimate. */
mp_result mp_int_string_len(mp_int z, mp_size radix);
/* Read zero-terminated string into z */
mp_result mp_int_read_string(mp_int z, mp_size radix, const char *str);
mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str,
mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str,
char **end);
/* Return the number of significant bits in z */

View File

@ -45,7 +45,7 @@
}
void
RC4_set_key(RC4_KEY *key, const int len, unsigned char *data)
RC4_set_key(RC4_KEY *key, const int len, const unsigned char *data)
{
int i, j;

View File

@ -42,5 +42,5 @@ typedef struct rc4_key {
unsigned int state[256];
} RC4_KEY;
void RC4_set_key(RC4_KEY *, const int, unsigned char *);
void RC4_set_key(RC4_KEY *, const int, const unsigned char *);
void RC4(RC4_KEY *, const int, const unsigned char *, unsigned char *);

View File

@ -205,6 +205,10 @@ imath_rsa_public_encrypt(int flen, const unsigned char* from,
mp_int_clear(&dec);
mp_int_clear(&e);
mp_int_clear(&n);
if (res != MP_OK)
return -4;
{
size_t ssize;
ssize = mp_int_unsigned_len(&enc);
@ -295,9 +299,10 @@ imath_rsa_private_encrypt(int flen, const unsigned char* from,
{
unsigned char *p, *p0;
mp_result res;
size_t size;
int size;
mpz_t in, out, n, e, b, bi;
int blinding = (rsa->flags & RSA_FLAG_NO_BLINDING) == 0;
int do_unblind = 0;
if (padding != RSA_PKCS1_PADDING)
return -1;
@ -327,13 +332,14 @@ imath_rsa_private_encrypt(int flen, const unsigned char* from,
if(mp_int_compare_zero(&in) < 0 ||
mp_int_compare(&in, &n) >= 0) {
size = 0;
size = -3;
goto out;
}
if (blinding) {
setup_blind(&n, &b, &bi);
blind(&in, &b, &e, &n);
do_unblind = 1;
}
if (rsa->p && rsa->q && rsa->dmp1 && rsa->dmq1 && rsa->iqmp) {
@ -352,6 +358,11 @@ imath_rsa_private_encrypt(int flen, const unsigned char* from,
mp_int_clear(&dmp1);
mp_int_clear(&dmq1);
mp_int_clear(&iqmp);
if (res != MP_OK) {
size = -4;
goto out;
}
} else {
mpz_t d;
@ -359,18 +370,15 @@ imath_rsa_private_encrypt(int flen, const unsigned char* from,
res = mp_int_exptmod(&in, &d, &n, &out);
mp_int_clear(&d);
if (res != MP_OK) {
size = 0;
size = -5;
goto out;
}
}
if (blinding) {
if (do_unblind)
unblind(&out, &bi, &n);
mp_int_clear(&b);
mp_int_clear(&bi);
}
{
if (size > 0) {
size_t ssize;
ssize = mp_int_unsigned_len(&out);
assert(size >= ssize);
@ -378,7 +386,12 @@ imath_rsa_private_encrypt(int flen, const unsigned char* from,
size = ssize;
}
out:
out:
if (do_unblind) {
mp_int_clear(&b);
mp_int_clear(&bi);
}
mp_int_clear(&e);
mp_int_clear(&n);
mp_int_clear(&in);
@ -396,6 +409,7 @@ imath_rsa_private_decrypt(int flen, const unsigned char* from,
size_t size;
mpz_t in, out, n, e, b, bi;
int blinding = (rsa->flags & RSA_FLAG_NO_BLINDING) == 0;
int do_unblind = 0;
if (padding != RSA_PKCS1_PADDING)
return -1;
@ -418,13 +432,14 @@ imath_rsa_private_decrypt(int flen, const unsigned char* from,
if(mp_int_compare_zero(&in) < 0 ||
mp_int_compare(&in, &n) >= 0) {
size = 0;
size = -2;
goto out;
}
if (blinding) {
setup_blind(&n, &b, &bi);
blind(&in, &b, &e, &n);
do_unblind = 1;
}
if (rsa->p && rsa->q && rsa->dmp1 && rsa->dmq1 && rsa->iqmp) {
@ -443,6 +458,12 @@ imath_rsa_private_decrypt(int flen, const unsigned char* from,
mp_int_clear(&dmp1);
mp_int_clear(&dmq1);
mp_int_clear(&iqmp);
if (res != MP_OK) {
size = -3;
goto out;
}
} else {
mpz_t d;
@ -454,16 +475,13 @@ imath_rsa_private_decrypt(int flen, const unsigned char* from,
res = mp_int_exptmod(&in, &d, &n, &out);
mp_int_clear(&d);
if (res != MP_OK) {
size = 0;
size = -4;
goto out;
}
}
if (blinding) {
if (do_unblind)
unblind(&out, &bi, &n);
mp_int_clear(&b);
mp_int_clear(&bi);
}
ptr = to;
{
@ -475,19 +493,26 @@ imath_rsa_private_decrypt(int flen, const unsigned char* from,
}
/* head zero was skipped by mp_int_to_unsigned */
if (*ptr != 2)
return -3;
if (*ptr != 2) {
size = -5;
goto out;
}
size--; ptr++;
while (size && *ptr != 0) {
size--; ptr++;
}
if (size == 0)
return -4;
return -6;
size--; ptr++;
memmove(to, ptr, size);
out:
out:
if (do_unblind) {
mp_int_clear(&b);
mp_int_clear(&bi);
}
mp_int_clear(&e);
mp_int_clear(&n);
mp_int_clear(&in);

View File

@ -278,7 +278,7 @@ RSA_check_key(const RSA *key)
return 0;
}
if (ret == sizeof(inbuf) && memcmp(buffer, inbuf, sizeof(inbuf)) == 0) {
if (ret == sizeof(inbuf) && ct_memcmp(buffer, inbuf, sizeof(inbuf)) == 0) {
free(buffer);
return 1;
}
@ -559,3 +559,38 @@ i2d_RSAPublicKey(RSA *rsa, unsigned char **pp)
return size;
}
RSA *
d2i_RSAPublicKey(RSA *rsa, const unsigned char **pp, size_t len)
{
RSAPublicKey data;
RSA *k = rsa;
size_t size;
int ret;
ret = decode_RSAPublicKey(*pp, len, &data, &size);
if (ret)
return NULL;
*pp += size;
if (k == NULL) {
k = RSA_new();
if (k == NULL) {
free_RSAPublicKey(&data);
return NULL;
}
}
k->n = heim_int2BN(&data.modulus);
k->e = heim_int2BN(&data.publicExponent);
free_RSAPublicKey(&data);
if (k->n == NULL || k->e == NULL) {
RSA_free(k);
return NULL;
}
return k;
}

View File

@ -64,6 +64,7 @@
#define d2i_RSAPrivateKey hc_d2i_RSAPrivateKey
#define i2d_RSAPrivateKey hc_i2d_RSAPrivateKey
#define i2d_RSAPublicKey hc_i2d_RSAPublicKey
#define d2i_RSAPublicKey hc_d2i_RSAPublicKey
/*
*
@ -173,5 +174,6 @@ RSA * d2i_RSAPrivateKey(RSA *, const unsigned char **, size_t);
int i2d_RSAPrivateKey(RSA *, unsigned char **);
int i2d_RSAPublicKey(RSA *, unsigned char **);
RSA * d2i_RSAPublicKey(RSA *, const unsigned char **, size_t);
#endif /* _HEIM_RSA_H */

View File

@ -102,10 +102,10 @@ hdb_get_dbinfo(krb5_context context, struct hdb_dbinfo **dbp)
dt = NULL;
databases = NULL;
db_binding = krb5_config_get(context, NULL, krb5_config_list,
"kdc",
"database",
NULL);
db_binding = krb5_config_get_list(context, NULL,
"kdc",
"database",
NULL);
if (db_binding) {
ret = get_dbinfo(context, db_binding, "default", &di);

View File

@ -49,7 +49,7 @@ struct hdb_cursor {
/*
* the format for HDB keytabs is:
* HDB:[database:file:mkey]
* HDB:[HDBFORMAT:database-specific-data[:mkey=mkey-file]]
*/
static krb5_error_code
@ -64,8 +64,8 @@ hdb_resolve(krb5_context context, const char *name, krb5_keytab id)
return ENOMEM;
}
db = name;
mkey = strchr(name, ':');
if(mkey == NULL || mkey[1] == '\0') {
mkey = strstr(name, ":mkey=");
if(mkey == NULL || mkey[5] == '\0') {
if(*name == '\0')
d->dbname = NULL;
else {
@ -78,19 +78,16 @@ hdb_resolve(krb5_context context, const char *name, krb5_keytab id)
}
d->mkey = NULL;
} else {
if((mkey - db) == 0) {
d->dbname = NULL;
} else {
d->dbname = malloc(mkey - db + 1);
if(d->dbname == NULL) {
free(d);
krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
return ENOMEM;
}
memmove(d->dbname, db, mkey - db);
d->dbname[mkey - db] = '\0';
d->dbname = malloc(mkey - db + 1);
if(d->dbname == NULL) {
free(d);
krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
return ENOMEM;
}
d->mkey = strdup(mkey + 1);
memmove(d->dbname, db, mkey - db);
d->dbname[mkey - db] = '\0';
d->mkey = strdup(mkey + 5);
if(d->mkey == NULL) {
free(d->dbname);
free(d);

Some files were not shown because too many files have changed in this diff Show More