summaryrefslogtreecommitdiff
path: root/source4/heimdal
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal')
-rw-r--r--source4/heimdal/cf/check-var.m43
-rw-r--r--source4/heimdal/kdc/digest.c214
-rw-r--r--source4/heimdal/kdc/kdc_locl.h3
-rw-r--r--source4/heimdal/kdc/kerberos5.c1
-rw-r--r--source4/heimdal/kdc/krb5tgs.c25
-rw-r--r--source4/heimdal/lib/asn1/krb5.asn19
-rw-r--r--source4/heimdal/lib/gssapi/gssapi_mech.h5
-rw-r--r--source4/heimdal/lib/gssapi/krb5/8003.c40
-rw-r--r--source4/heimdal/lib/gssapi/krb5/aeap.c6
-rw-r--r--source4/heimdal/lib/gssapi/krb5/arcfour.c70
-rwxr-xr-xsource4/heimdal/lib/gssapi/krb5/cfx.c380
-rw-r--r--source4/heimdal/lib/gssapi/krb5/creds.c1
-rw-r--r--source4/heimdal/lib/gssapi/krb5/decapsulate.c8
-rw-r--r--source4/heimdal/lib/gssapi/krb5/external.c1
-rw-r--r--source4/heimdal/lib/gssapi/krb5/get_mic.c27
-rw-r--r--source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h5
-rw-r--r--source4/heimdal/lib/gssapi/krb5/init_sec_context.c17
-rw-r--r--source4/heimdal/lib/gssapi/krb5/prf.c1
-rw-r--r--source4/heimdal/lib/gssapi/krb5/unwrap.c61
-rw-r--r--source4/heimdal/lib/gssapi/krb5/verify_mic.c39
-rw-r--r--source4/heimdal/lib/gssapi/krb5/wrap.c45
-rw-r--r--source4/heimdal/lib/gssapi/mech/context.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c16
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_add_cred.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c19
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_buffer_set.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_compare_name.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_context_time.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_display_name.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_display_status.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_export_name.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_get_mic.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_import_name.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c6
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_context.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_krb5.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_mech_switch.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_names.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_oid_equal.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_oid_to_str.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_process_context_token.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_pseudo_random.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_buffer.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_cred.c23
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_name.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_oid.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_seal.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_sign.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_unseal.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_unwrap.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_utils.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_verify.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_verify_mic.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_wrap.c1
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c1
-rw-r--r--source4/heimdal/lib/gssapi/spnego/accept_sec_context.c42
-rw-r--r--source4/heimdal/lib/gssapi/spnego/compat.c7
-rw-r--r--source4/heimdal/lib/gssapi/spnego/context_stubs.c104
-rw-r--r--source4/heimdal/lib/gssapi/spnego/cred_stubs.c139
-rw-r--r--source4/heimdal/lib/gssapi/spnego/external.c9
-rw-r--r--source4/heimdal/lib/gssapi/spnego/init_sec_context.c16
-rw-r--r--source4/heimdal/lib/gssapi/spnego/spnego_locl.h4
-rw-r--r--source4/heimdal/lib/hcrypto/des.c1
-rw-r--r--source4/heimdal/lib/hcrypto/evp-aes-cts.c273
-rw-r--r--source4/heimdal/lib/hcrypto/evp-cc.c621
-rw-r--r--source4/heimdal/lib/hcrypto/evp-cc.h91
-rw-r--r--source4/heimdal/lib/hcrypto/evp-hcrypto.c568
-rw-r--r--source4/heimdal/lib/hcrypto/evp-hcrypto.h92
-rw-r--r--source4/heimdal/lib/hcrypto/evp.c445
-rw-r--r--source4/heimdal/lib/hcrypto/evp.h35
-rw-r--r--source4/heimdal/lib/hcrypto/imath/imath.c447
-rw-r--r--source4/heimdal/lib/hcrypto/imath/imath.h12
-rw-r--r--source4/heimdal/lib/hcrypto/rc4.c2
-rw-r--r--source4/heimdal/lib/hcrypto/rc4.h2
-rw-r--r--source4/heimdal/lib/hcrypto/rsa-imath.c63
-rw-r--r--source4/heimdal/lib/hcrypto/rsa.c37
-rw-r--r--source4/heimdal/lib/hcrypto/rsa.h2
-rw-r--r--source4/heimdal/lib/hdb/dbinfo.c8
-rw-r--r--source4/heimdal/lib/hdb/keytab.c27
-rw-r--r--source4/heimdal/lib/hx509/ca.c14
-rw-r--r--source4/heimdal/lib/hx509/cert.c33
-rw-r--r--source4/heimdal/lib/hx509/crypto.c277
-rw-r--r--source4/heimdal/lib/hx509/ks_dir.c2
-rw-r--r--source4/heimdal/lib/hx509/name.c12
-rw-r--r--source4/heimdal/lib/hx509/print.c2
-rw-r--r--source4/heimdal/lib/hx509/revoke.c6
-rw-r--r--source4/heimdal/lib/krb5/cache.c44
-rw-r--r--source4/heimdal/lib/krb5/config_file.c357
-rw-r--r--source4/heimdal/lib/krb5/context.c85
-rw-r--r--source4/heimdal/lib/krb5/creds.c12
-rw-r--r--source4/heimdal/lib/krb5/crypto.c424
-rw-r--r--source4/heimdal/lib/krb5/init_creds_pw.c64
-rw-r--r--source4/heimdal/lib/krb5/keyblock.c6
-rw-r--r--source4/heimdal/lib/krb5/krb5_locl.h3
-rw-r--r--source4/heimdal/lib/krb5/krbhst.c104
-rw-r--r--source4/heimdal/lib/krb5/log.c16
-rw-r--r--source4/heimdal/lib/krb5/pkinit.c29
-rw-r--r--source4/heimdal/lib/krb5/principal.c78
-rw-r--r--source4/heimdal/lib/krb5/replay.c19
-rw-r--r--source4/heimdal/lib/krb5/send_to_kdc.c7
-rw-r--r--source4/heimdal/lib/krb5/store.c265
-rw-r--r--source4/heimdal/lib/krb5/store_mem.c6
-rw-r--r--source4/heimdal/lib/krb5/ticket.c77
-rw-r--r--source4/heimdal/lib/krb5/warn.c2
-rw-r--r--source4/heimdal/lib/ntlm/ntlm.c104
-rw-r--r--source4/heimdal/lib/roken/base64.c1
-rw-r--r--source4/heimdal/lib/roken/ct.c64
-rw-r--r--source4/heimdal/lib/roken/resolve.c2
-rw-r--r--source4/heimdal/lib/roken/rkpty.c2
-rw-r--r--source4/heimdal/lib/roken/roken-common.h2
-rw-r--r--source4/heimdal/lib/roken/roken.h.in34
-rw-r--r--source4/heimdal/lib/roken/vis.c6
-rw-r--r--source4/heimdal/lib/wind/map.c2
-rw-r--r--source4/heimdal/lib/wind/normalize.c2
-rw-r--r--source4/heimdal/lib/wind/stringprep.c2
-rw-r--r--source4/heimdal/lib/wind/utf8.c2
137 files changed, 4114 insertions, 2178 deletions
diff --git a/source4/heimdal/cf/check-var.m4 b/source4/heimdal/cf/check-var.m4
index f81f3524c1..2fd7bca6f0 100644
--- a/source4/heimdal/cf/check-var.m4
+++ b/source4/heimdal/cf/check-var.m4
@@ -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
diff --git a/source4/heimdal/kdc/digest.c b/source4/heimdal/kdc/digest.c
index d13507fc1f..1a383fa205 100644
--- a/source4/heimdal/kdc/digest.c
+++ b/source4/heimdal/kdc/digest.c
@@ -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));
+
+ EVP_DigestFinal_ex(ctx, md, NULL);
- MD5_Final(md, &ctx);
+ 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);
-
- 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, 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);
+
+ 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;
+
+ 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);
- MD4_Init(&ctx);
- MD4_Update(&ctx,
- key->key.keyvalue.data, key->key.keyvalue.length);
- MD4_Final(sessionkey, &ctx);
+ 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));
diff --git a/source4/heimdal/kdc/kdc_locl.h b/source4/heimdal/kdc/kdc_locl.h
index 024937e763..f2da03b5e6 100644
--- a/source4/heimdal/kdc/kdc_locl.h
+++ b/source4/heimdal/kdc/kdc_locl.h
@@ -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;
diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c
index 8edc07a49b..0a9d4a5ca4 100644
--- a/source4/heimdal/kdc/kerberos5.c
+++ b/source4/heimdal/kdc/kerberos5.c
@@ -1747,6 +1747,7 @@ _kdc_as_rep(krb5_context context,
config,
server,
setype,
+ client->entry.principal,
NULL,
NULL,
&et);
diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c
index 635eb27e75..c3b0aaa89e 100644
--- a/source4/heimdal/kdc/krb5tgs.c
+++ b/source4/heimdal/kdc/krb5tgs.c
@@ -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);
diff --git a/source4/heimdal/lib/asn1/krb5.asn1 b/source4/heimdal/lib/asn1/krb5.asn1
index 7080b095f8..adc09ac680 100644
--- a/source4/heimdal/lib/asn1/krb5.asn1
+++ b/source4/heimdal/lib/asn1/krb5.asn1
@@ -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{
diff --git a/source4/heimdal/lib/gssapi/gssapi_mech.h b/source4/heimdal/lib/gssapi/gssapi_mech.h
index 206a24ef74..65cabf54d1 100644
--- a/source4/heimdal/lib/gssapi/gssapi_mech.h
+++ b/source4/heimdal/lib/gssapi/gssapi_mech.h
@@ -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;
diff --git a/source4/heimdal/lib/gssapi/krb5/8003.c b/source4/heimdal/lib/gssapi/krb5/8003.c
index a6f0165e72..2c53d67003 100644
--- a/source4/heimdal/lib/gssapi/krb5/8003.c
+++ b/source4/heimdal/lib/gssapi/krb5/8003.c
@@ -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;
}
diff --git a/source4/heimdal/lib/gssapi/krb5/aeap.c b/source4/heimdal/lib/gssapi/krb5/aeap.c
index 38a5ac2dbe..f1aee4bbbf 100644
--- a/source4/heimdal/lib/gssapi/krb5/aeap.c
+++ b/source4/heimdal/lib/gssapi/krb5/aeap.c
@@ -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,
diff --git a/source4/heimdal/lib/gssapi/krb5/arcfour.c b/source4/heimdal/lib/gssapi/krb5/arcfour.c
index e7331b0119..dc59e997bd 100644
--- a/source4/heimdal/lib/gssapi/krb5/arcfour.c
+++ b/source4/heimdal/lib/gssapi/krb5/arcfour.c
@@ -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;
diff --git a/source4/heimdal/lib/gssapi/krb5/cfx.c b/source4/heimdal/lib/gssapi/krb5/cfx.c
index 7cc7ee1e74..1a6e975279 100755
--- a/source4/heimdal/lib/gssapi/krb5/cfx.c
+++ b/source4/heimdal/lib/gssapi/krb5/cfx.c
@@ -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;
}
diff --git a/source4/heimdal/lib/gssapi/krb5/creds.c b/source4/heimdal/lib/gssapi/krb5/creds.c
index 68cb766bc3..fd40617040 100644
--- a/source4/heimdal/lib/gssapi/krb5/creds.c
+++ b/source4/heimdal/lib/gssapi/krb5/creds.c
@@ -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;
}
diff --git a/source4/heimdal/lib/gssapi/krb5/decapsulate.c b/source4/heimdal/lib/gssapi/krb5/decapsulate.c
index 7ccf0b0f79..640c064d0b 100644
--- a/source4/heimdal/lib/gssapi/krb5/decapsulate.c
+++ b/source4/heimdal/lib/gssapi/krb5/decapsulate.c
@@ -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;
diff --git a/source4/heimdal/lib/gssapi/krb5/external.c b/source4/heimdal/lib/gssapi/krb5/external.c
index fc835bd845..fd81f3ebeb 100644
--- a/source4/heimdal/lib/gssapi/krb5/external.c
+++ b/source4/heimdal/lib/gssapi/krb5/external.c
@@ -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,
diff --git a/source4/heimdal/lib/gssapi/krb5/get_mic.c b/source4/heimdal/lib/gssapi/krb5/get_mic.c
index ad3009c73e..f3f7fff8ae 100644
--- a/source4/heimdal/lib/gssapi/krb5/get_mic.c
+++ b/source4/heimdal/lib/gssapi/krb5/get_mic.c
@@ -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,
diff --git a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h
index aadb80db0d..d91670821a 100644
--- a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h
+++ b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h
@@ -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
*/
diff --git a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
index b269d06798..1954c101c7 100644
--- a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
+++ b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
@@ -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;
diff --git a/source4/heimdal/lib/gssapi/krb5/prf.c b/source4/heimdal/lib/gssapi/krb5/prf.c
index 76ae3b78ed..737ccb6834 100644
--- a/source4/heimdal/lib/gssapi/krb5/prf.c
+++ b/source4/heimdal/lib/gssapi/krb5/prf.c
@@ -132,6 +132,7 @@ _gsskrb5_pseudo_random(OM_uint32 *minor_status,
krb5_data_free(&output);
num++;
}
+ free(input.data);
krb5_crypto_destroy(context, crypto);
diff --git a/source4/heimdal/lib/gssapi/krb5/unwrap.c b/source4/heimdal/lib/gssapi/krb5/unwrap.c
index 20cf952b4e..5e0042e28b 100644
--- a/source4/heimdal/lib/gssapi/krb5/unwrap.c
+++ b/source4/heimdal/lib/gssapi/krb5/unwrap.c
@@ -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,
diff --git a/source4/heimdal/lib/gssapi/krb5/verify_mic.c b/source4/heimdal/lib/gssapi/krb5/verify_mic.c
index c7e16e81f7..0b5b6e1ccd 100644
--- a/source4/heimdal/lib/gssapi/krb5/verify_mic.c
+++ b/source4/heimdal/lib/gssapi/krb5/verify_mic.c
@@ -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,
diff --git a/source4/heimdal/lib/gssapi/krb5/wrap.c b/source4/heimdal/lib/gssapi/krb5/wrap.c
index 3de13f908f..9078fb3dd7 100644
--- a/source4/heimdal/lib/gssapi/krb5/wrap.c
+++ b/source4/heimdal/lib/gssapi/krb5/wrap.c
@@ -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,
diff --git a/source4/heimdal/lib/gssapi/mech/context.c b/source4/heimdal/lib/gssapi/mech/context.c
index b032d8aa0e..96e5edc32b 100644
--- a/source4/heimdal/lib/gssapi/mech/context.c
+++ b/source4/heimdal/lib/gssapi/mech/context.c
@@ -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;
diff --git a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
index 134511f34b..1529ab1137 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
@@ -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;
diff --git a/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c b/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c
index b1bc7dd981..75a7978d89 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_acquire_cred(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_add_cred.c b/source4/heimdal/lib/gssapi/mech/gss_add_cred.c
index d190852884..08c7882784 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_add_cred.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_add_cred.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
static struct _gss_mechanism_cred *
_gss_copy_cred(struct _gss_mechanism_cred *mc)
diff --git a/source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c b/source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c
index d10b1e7e43..b866125291 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c
@@ -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,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c b/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c
index 9f0bb4cce3..58863c3112 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c
@@ -31,7 +31,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_create_empty_buffer_set
diff --git a/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c b/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c
index db976f2453..1bb94b3468 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
/**
* gss_canonicalize_name takes a Internal Name (IN) and converts in into a
diff --git a/source4/heimdal/lib/gssapi/mech/gss_compare_name.c b/source4/heimdal/lib/gssapi/mech/gss_compare_name.c
index 3f2d0013c5..9481218de2 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_compare_name.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_compare_name.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_compare_name(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_context_time.c b/source4/heimdal/lib/gssapi/mech/gss_context_time.c
index df89612060..d99f71f77a 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_context_time.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_context_time.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_context_time(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c b/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c
index 8858f28498..36337a5435 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_create_empty_oid_set(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c b/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c
index 6681fc5a34..8db0832d86 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c
@@ -32,7 +32,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_decapsulate_token(gss_buffer_t input_token,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c
index 96abae6b33..c2575927c3 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_delete_sec_context(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_display_name.c b/source4/heimdal/lib/gssapi/mech/gss_display_name.c
index d720ffe880..0b75592246 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_display_name.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_display_name.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_display_name(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_display_status.c b/source4/heimdal/lib/gssapi/mech/gss_display_status.c
index daa62bfcd9..60c5b8f523 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_display_status.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_display_status.c
@@ -59,7 +59,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
static const char *
calling_error(OM_uint32 v)
diff --git a/source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c b/source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c
index 1690ae6c51..87775878ef 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c
@@ -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,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c b/source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c
index b6aa226fda..165b07e5ae 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c
@@ -32,7 +32,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 gss_duplicate_oid (
OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c b/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c
index b5434be85a..e14b00f9ce 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c
@@ -32,7 +32,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_encapsulate_token(gss_buffer_t input_token,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_export_name.c b/source4/heimdal/lib/gssapi/mech/gss_export_name.c
index 7c1e6791da..7f7c1afe68 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_export_name.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_export_name.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_export_name(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c
index f3a6dc4fb5..0fc19e2af7 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_export_sec_context(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_get_mic.c b/source4/heimdal/lib/gssapi/mech/gss_get_mic.c
index 3a0f3fb757..f4921b60db 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_get_mic.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_get_mic.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_get_mic(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_import_name.c b/source4/heimdal/lib/gssapi/mech/gss_import_name.c
index c1dffdc614..19ab75a84c 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_import_name.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_import_name.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
static OM_uint32
_gss_import_export_name(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c
index 01ca9f10df..e08d3b7af4 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_import_sec_context(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c b/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c
index 34c0bb55d8..ab95a18ee6 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_indicate_mechs(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c
index 579000a7ec..dfebe26109 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c
@@ -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,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c
index 8872f121d0..e000af00ef 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_inquire_context(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c
index 3587572672..e5faf58764 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
#define AUSAGE 1
#define IUSAGE 2
diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c
index 47a2eaf279..39c5e711b7 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_inquire_cred_by_mech(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c
index 733d919fd9..3b821ce823 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c
@@ -31,7 +31,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_inquire_cred_by_oid (OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c
index e953ccb5da..f0e23e664a 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_inquire_mechs_for_name(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c
index a630d76216..c796f05227 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_inquire_names_for_mech(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c
index 9ba892dc0e..ffa0c44fa3 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c
@@ -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,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_krb5.c b/source4/heimdal/lib/gssapi/mech/gss_krb5.c
index 5d883c45c2..1611d91d02 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_krb5.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_krb5.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
#include <krb5.h>
#include <roken.h>
diff --git a/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c b/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c
index 3321819d28..d060badfe1 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c
@@ -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);
diff --git a/source4/heimdal/lib/gssapi/mech/gss_names.c b/source4/heimdal/lib/gssapi/mech/gss_names.c
index ada53d0bfd..6a7ccd5c71 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_names.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_names.c
@@ -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,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c b/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c
index a99eb09e50..93ee6b2a2d 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c
@@ -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)
diff --git a/source4/heimdal/lib/gssapi/mech/gss_oid_to_str.c b/source4/heimdal/lib/gssapi/mech/gss_oid_to_str.c
index 92d997bed9..114e7d63e4 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_oid_to_str.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_oid_to_str.c
@@ -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)
diff --git a/source4/heimdal/lib/gssapi/mech/gss_process_context_token.c b/source4/heimdal/lib/gssapi/mech/gss_process_context_token.c
index 9dc3f5b904..738ff7d8e2 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_process_context_token.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_process_context_token.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_process_context_token(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_pseudo_random.c b/source4/heimdal/lib/gssapi/mech/gss_pseudo_random.c
index 771efcb434..96b40a6af6 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_pseudo_random.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_pseudo_random.c
@@ -34,7 +34,6 @@
/* $Id$ */
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_pseudo_random(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_buffer.c b/source4/heimdal/lib/gssapi/mech/gss_release_buffer.c
index 1af5289157..9aad034ab2 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_release_buffer.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_release_buffer.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_release_buffer(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_cred.c b/source4/heimdal/lib/gssapi/mech/gss_release_cred.c
index 40777fa2a1..463fddb2ba 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_release_cred.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_release_cred.c
@@ -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)
diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_name.c b/source4/heimdal/lib/gssapi/mech/gss_release_name.c
index c5e348d5c0..84553ee05d 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_release_name.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_release_name.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_release_name(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_oid.c b/source4/heimdal/lib/gssapi/mech/gss_release_oid.c
index 8d0ea4367c..458e94d711 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_release_oid.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_release_oid.c
@@ -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)
diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c b/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c
index 0ccb9e4dc6..f875d39d0c 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_release_oid_set(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_seal.c b/source4/heimdal/lib/gssapi/mech/gss_seal.c
index f6636456ea..8c1e9eba1c 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_seal.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_seal.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_seal(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c b/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c
index 20eaa14d9e..86a136159e 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c
@@ -31,7 +31,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_set_cred_option (OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c b/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c
index 735d59322e..ca0ec00ef7 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c
@@ -31,7 +31,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_set_sec_context_option (OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_sign.c b/source4/heimdal/lib/gssapi/mech/gss_sign.c
index 1d73641355..8a1b1e363f 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_sign.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_sign.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_sign(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c b/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c
index ca1dca8fad..7995f4df00 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_test_oid_set_member(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_unseal.c b/source4/heimdal/lib/gssapi/mech/gss_unseal.c
index 539e65a01c..8815790575 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_unseal.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_unseal.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_unseal(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_unwrap.c b/source4/heimdal/lib/gssapi/mech/gss_unwrap.c
index 693bbe020b..7285e46598 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_unwrap.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_unwrap.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_unwrap(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_utils.c b/source4/heimdal/lib/gssapi/mech/gss_utils.c
index 6e05acff03..2071621b23 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_utils.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_utils.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32
_gss_copy_oid(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_verify.c b/source4/heimdal/lib/gssapi/mech/gss_verify.c
index f287cb4816..e60d6507be 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_verify.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_verify.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_verify(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c b/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c
index 60ef3bff85..c535e3ffce 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_verify_mic(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_wrap.c b/source4/heimdal/lib/gssapi/mech/gss_wrap.c
index 9476d01ddd..fb8a17bbe6 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_wrap.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_wrap.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_wrap(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c b/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c
index a5a80b21d7..49af364668 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c
@@ -27,7 +27,6 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
OM_uint32 GSSAPI_LIB_FUNCTION
gss_wrap_size_limit(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c
index 2bdfc28ebf..247c25611f 100644
--- a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c
+++ b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c
@@ -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;
diff --git a/source4/heimdal/lib/gssapi/spnego/compat.c b/source4/heimdal/lib/gssapi/spnego/compat.c
index ee25b59435..b2f535e58f 100644
--- a/source4/heimdal/lib/gssapi/spnego/compat.c
+++ b/source4/heimdal/lib/gssapi/spnego/compat.c
@@ -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,
diff --git a/source4/heimdal/lib/gssapi/spnego/context_stubs.c b/source4/heimdal/lib/gssapi/spnego/context_stubs.c
index 1998c44edf..c0d47b9f63 100644
--- a/source4/heimdal/lib/gssapi/spnego/context_stubs.c
+++ b/source4/heimdal/lib/gssapi/spnego/context_stubs.c
@@ -643,84 +643,70 @@ OM_uint32 _gss_spnego_duplicate_name (
return gss_duplicate_name(minor_status, src_name, dest_name);
}
-#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)
+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 ctx = (gssspnego_ctx)context_handle;
*minor_status = 0;
- if (context_handle == GSS_C_NO_CONTEXT) {
+ if (ctx == NULL || ctx->negotiated_ctx_id == 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);
+ return gss_wrap_iov(minor_status, ctx->negotiated_ctx_id,
+ conf_req_flag, qop_req, conf_state,
+ iov, iov_count);
}
-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
- )
+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 ctx = (gssspnego_ctx)context_handle;
*minor_status = 0;
- if (context_handle == GSS_C_NO_CONTEXT) {
+ if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
return GSS_S_NO_CONTEXT;
- }
- ctx = (gssspnego_ctx)context_handle;
+ return gss_unwrap_iov(minor_status,
+ ctx->negotiated_ctx_id,
+ conf_state, qop_state,
+ iov, iov_count);
+}
- if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
- return GSS_S_NO_CONTEXT;
- }
+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;
- 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;
- }
+ *minor_status = 0;
+
+ if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
+ return GSS_S_NO_CONTEXT;
- 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);
+ 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_complete_auth_token
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
diff --git a/source4/heimdal/lib/gssapi/spnego/cred_stubs.c b/source4/heimdal/lib/gssapi/spnego/cred_stubs.c
index a10a10f1ef..b1eb0be6da 100644
--- a/source4/heimdal/lib/gssapi/spnego/cred_stubs.c
+++ b/source4/heimdal/lib/gssapi/spnego/cred_stubs.c
@@ -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);
}
diff --git a/source4/heimdal/lib/gssapi/spnego/external.c b/source4/heimdal/lib/gssapi/spnego/external.c
index f3edcba389..9d50a61a75 100644
--- a/source4/heimdal/lib/gssapi/spnego/external.c
+++ b/source4/heimdal/lib/gssapi/spnego/external.c
@@ -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
diff --git a/source4/heimdal/lib/gssapi/spnego/init_sec_context.c b/source4/heimdal/lib/gssapi/spnego/init_sec_context.c
index ac32432d55..6afd524a5b 100644
--- a/source4/heimdal/lib/gssapi/spnego/init_sec_context.c
+++ b/source4/heimdal/lib/gssapi/spnego/init_sec_context.c
@@ -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,
diff --git a/source4/heimdal/lib/gssapi/spnego/spnego_locl.h b/source4/heimdal/lib/gssapi/spnego/spnego_locl.h
index 44fa8b117d..e8cad14881 100644
--- a/source4/heimdal/lib/gssapi/spnego/spnego_locl.h
+++ b/source4/heimdal/lib/gssapi/spnego/spnego_locl.h
@@ -74,10 +74,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;
gss_OID negotiated_mech_type;
diff --git a/source4/heimdal/lib/hcrypto/des.c b/source4/heimdal/lib/hcrypto/des.c
index 7dc4823b59..c9067d7bcc 100644
--- a/source4/heimdal/lib/hcrypto/des.c
+++ b/source4/heimdal/lib/hcrypto/des.c
@@ -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;
diff --git a/source4/heimdal/lib/hcrypto/evp-aes-cts.c b/source4/heimdal/lib/hcrypto/evp-aes-cts.c
deleted file mode 100644
index 66f87982c0..0000000000
--- a/source4/heimdal/lib/hcrypto/evp-aes-cts.c
+++ /dev/null
@@ -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;
-}
diff --git a/source4/heimdal/lib/hcrypto/evp-cc.c b/source4/heimdal/lib/hcrypto/evp-cc.c
new file mode 100644
index 0000000000..1bf8ca8af9
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/evp-cc.c
@@ -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__ */
+
diff --git a/source4/heimdal/lib/hcrypto/evp-cc.h b/source4/heimdal/lib/hcrypto/evp-cc.h
new file mode 100644
index 0000000000..d2df771bc0
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/evp-cc.h
@@ -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 */
diff --git a/source4/heimdal/lib/hcrypto/evp-hcrypto.c b/source4/heimdal/lib/hcrypto/evp-hcrypto.c
index d176e2edfa..699fc667b0 100644
--- a/source4/heimdal/lib/hcrypto/evp-hcrypto.c
+++ b/source4/heimdal/lib/hcrypto/evp-hcrypto.c
@@ -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;
+}
diff --git a/source4/heimdal/lib/hcrypto/evp-hcrypto.h b/source4/heimdal/lib/hcrypto/evp-hcrypto.h
new file mode 100644
index 0000000000..c0fb89af71
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/evp-hcrypto.h
@@ -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 */
diff --git a/source4/heimdal/lib/hcrypto/evp.c b/source4/heimdal/lib/hcrypto/evp.c
index ac6cac972a..006db35939 100644
--- a/source4/heimdal/lib/hcrypto/evp.c
+++ b/source4/heimdal/lib/hcrypto/evp.c
@@ -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)
-{
- 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;
+EVP_md5(void) HC_DEPRECATED_CRYPTO
+{
+ return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, md5);
}
/**
@@ -433,18 +410,9 @@ EVP_md5(void)
*/
const EVP_MD *
-EVP_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;
+EVP_md4(void) HC_DEPRECATED_CRYPTO
+{
+ return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, md4);
}
/**
@@ -456,18 +424,9 @@ EVP_md4(void)
*/
const EVP_MD *
-EVP_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;
+EVP_md2(void) HC_DEPRECATED_CRYPTO
+{
+ 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);
}
/*
diff --git a/source4/heimdal/lib/hcrypto/evp.h b/source4/heimdal/lib/hcrypto/evp.h
index 0086a06960..600f69b7a5 100644
--- a/source4/heimdal/lib/hcrypto/evp.h
+++ b/source4/heimdal/lib/hcrypto/evp.h
@@ -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 */
diff --git a/source4/heimdal/lib/hcrypto/imath/imath.c b/source4/heimdal/lib/hcrypto/imath/imath.c
index f8e4154cdc..4e47a76ce2 100644
--- a/source4/heimdal/lib/hcrypto/imath/imath.c
+++ b/source4/heimdal/lib/hcrypto/imath/imath.c
@@ -2,7 +2,7 @@
Name: imath.c
Purpose: Arbitrary precision integer arithmetic routines.
Author: M. J. Fromberger <http://spinning-yarns.org/michael/>
- Info: $Id: imath.c 645 2008-08-03 04:00:30Z sting $
+ Info: $Id: imath.c 826 2009-02-11 16:21:04Z sting $
Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved.
@@ -40,7 +40,9 @@
#include <assert.h>
#if DEBUG
-#define static
+#define STATIC /* public */
+#else
+#define STATIC static
#endif
/* {{{ Constants */
@@ -58,8 +60,8 @@ const mp_result MP_MINERR = -6;
const mp_sign MP_NEG = 1; /* value is strictly negative */
const mp_sign MP_ZPOS = 0; /* value is non-negative */
-static const char *s_unknown_err = "unknown result code";
-static const char *s_error_msg[] = {
+STATIC const char *s_unknown_err = "unknown result code";
+STATIC const char *s_error_msg[] = {
"error code 0",
"boolean true",
"out of memory",
@@ -72,7 +74,7 @@ static const char *s_error_msg[] = {
/* }}} */
-/* Argument checking macros
+/* Argument checking macros
Use CHECK() where a return value is required; NRCHECK() elsewhere */
#define CHECK(TEST) assert(TEST)
#define NRCHECK(TEST) assert(TEST)
@@ -88,7 +90,7 @@ static const char *s_error_msg[] = {
The use of this table eliminates a dependency upon linkage against
the standard math libraries.
*/
-static const double s_log2[] = {
+STATIC const double s_log2[] = {
0.000000000, 0.000000000, 1.000000000, 0.630929754, /* 0 1 2 3 */
0.500000000, 0.430676558, 0.386852807, 0.356207187, /* 4 5 6 7 */
0.333333333, 0.315464877, 0.301029996, 0.289064826, /* 8 9 10 11 */
@@ -172,144 +174,144 @@ do{mp_size ua_=MP_USED(X),o_=ua_+ua_;ZERO(MP_DIGITS(Z),o_);\
#if IMATH_TEST
mp_size default_precision = MP_DEFAULT_PREC;
#else
-static const mp_size default_precision = MP_DEFAULT_PREC;
+STATIC const mp_size default_precision = MP_DEFAULT_PREC;
#endif
/* Minimum number of digits to invoke recursive multiply */
#if IMATH_TEST
mp_size multiply_threshold = MP_MULT_THRESH;
#else
-static const mp_size multiply_threshold = MP_MULT_THRESH;
+STATIC const mp_size multiply_threshold = MP_MULT_THRESH;
#endif
/* }}} */
/* Allocate a buffer of (at least) num digits, or return
NULL if that couldn't be done. */
-static mp_digit *s_alloc(mp_size num);
+STATIC mp_digit *s_alloc(mp_size num);
/* Release a buffer of digits allocated by s_alloc(). */
-static void s_free(void *ptr);
+STATIC void s_free(void *ptr);
/* Insure that z has at least min digits allocated, resizing if
necessary. Returns true if successful, false if out of memory. */
-static int s_pad(mp_int z, mp_size min);
+STATIC int s_pad(mp_int z, mp_size min);
/* Fill in a "fake" mp_int on the stack with a given value */
-static void s_fake(mp_int z, mp_small value, mp_digit vbuf[]);
+STATIC void s_fake(mp_int z, mp_small value, mp_digit vbuf[]);
/* Compare two runs of digits of given length, returns <0, 0, >0 */
-static int s_cdig(mp_digit *da, mp_digit *db, mp_size len);
+STATIC int s_cdig(mp_digit *da, mp_digit *db, mp_size len);
/* Pack the unsigned digits of v into array t */
-static int s_vpack(mp_small v, mp_digit t[]);
+STATIC int s_vpack(mp_small v, mp_digit t[]);
/* Compare magnitudes of a and b, returns <0, 0, >0 */
-static int s_ucmp(mp_int a, mp_int b);
+STATIC int s_ucmp(mp_int a, mp_int b);
/* Compare magnitudes of a and v, returns <0, 0, >0 */
-static int s_vcmp(mp_int a, mp_small v);
+STATIC int s_vcmp(mp_int a, mp_small v);
/* Unsigned magnitude addition; assumes dc is big enough.
Carry out is returned (no memory allocated). */
-static mp_digit s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc,
+STATIC mp_digit s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc,
mp_size size_a, mp_size size_b);
/* Unsigned magnitude subtraction. Assumes dc is big enough. */
-static void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc,
+STATIC void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc,
mp_size size_a, mp_size size_b);
/* Unsigned recursive multiplication. Assumes dc is big enough. */
-static int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc,
+STATIC int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc,
mp_size size_a, mp_size size_b);
/* Unsigned magnitude multiplication. Assumes dc is big enough. */
-static void s_umul(mp_digit *da, mp_digit *db, mp_digit *dc,
+STATIC void s_umul(mp_digit *da, mp_digit *db, mp_digit *dc,
mp_size size_a, mp_size size_b);
/* Unsigned recursive squaring. Assumes dc is big enough. */
-static int s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a);
+STATIC int s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a);
/* Unsigned magnitude squaring. Assumes dc is big enough. */
-static void s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a);
+STATIC void s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a);
/* Single digit addition. Assumes a is big enough. */
-static void s_dadd(mp_int a, mp_digit b);
+STATIC void s_dadd(mp_int a, mp_digit b);
/* Single digit multiplication. Assumes a is big enough. */
-static void s_dmul(mp_int a, mp_digit b);
+STATIC void s_dmul(mp_int a, mp_digit b);
/* Single digit multiplication on buffers; assumes dc is big enough. */
-static void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc,
+STATIC void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc,
mp_size size_a);
-/* Single digit division. Replaces a with the quotient,
+/* Single digit division. Replaces a with the quotient,
returns the remainder. */
-static mp_digit s_ddiv(mp_int a, mp_digit b);
+STATIC mp_digit s_ddiv(mp_int a, mp_digit b);
/* Quick division by a power of 2, replaces z (no allocation) */
-static void s_qdiv(mp_int z, mp_size p2);
+STATIC void s_qdiv(mp_int z, mp_size p2);
/* Quick remainder by a power of 2, replaces z (no allocation) */
-static void s_qmod(mp_int z, mp_size p2);
+STATIC void s_qmod(mp_int z, mp_size p2);
-/* Quick multiplication by a power of 2, replaces z.
+/* Quick multiplication by a power of 2, replaces z.
Allocates if necessary; returns false in case this fails. */
-static int s_qmul(mp_int z, mp_size p2);
+STATIC int s_qmul(mp_int z, mp_size p2);
/* Quick subtraction from a power of 2, replaces z.
Allocates if necessary; returns false in case this fails. */
-static int s_qsub(mp_int z, mp_size p2);
+STATIC int s_qsub(mp_int z, mp_size p2);
/* Return maximum k such that 2^k divides z. */
-static int s_dp2k(mp_int z);
+STATIC int s_dp2k(mp_int z);
/* Return k >= 0 such that z = 2^k, or -1 if there is no such k. */
-static int s_isp2(mp_int z);
+STATIC int s_isp2(mp_int z);
/* Set z to 2^k. May allocate; returns false in case this fails. */
-static int s_2expt(mp_int z, mp_small k);
+STATIC int s_2expt(mp_int z, mp_small k);
/* Normalize a and b for division, returns normalization constant */
-static int s_norm(mp_int a, mp_int b);
+STATIC int s_norm(mp_int a, mp_int b);
/* Compute constant mu for Barrett reduction, given modulus m, result
replaces z, m is untouched. */
-static mp_result s_brmu(mp_int z, mp_int m);
+STATIC mp_result s_brmu(mp_int z, mp_int m);
/* Reduce a modulo m, using Barrett's algorithm. */
-static int s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2);
+STATIC int s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2);
/* Modular exponentiation, using Barrett reduction */
-static mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c);
+STATIC mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c);
/* Unsigned magnitude division. Assumes |a| > |b|. Allocates
temporaries; overwrites a with quotient, b with remainder. */
-static mp_result s_udiv(mp_int a, mp_int b);
+STATIC mp_result s_udiv(mp_int a, mp_int b);
/* Compute the number of digits in radix r required to represent the
given value. Does not account for sign flags, terminators, etc. */
-static int s_outlen(mp_int z, mp_size r);
+STATIC int s_outlen(mp_int z, mp_size r);
/* Guess how many digits of precision will be needed to represent a
radix r value of the specified number of digits. Returns a value
guaranteed to be no smaller than the actual number required. */
-static mp_size s_inlen(int len, mp_size r);
+STATIC mp_size s_inlen(int len, mp_size r);
-/* Convert a character to a digit value in radix r, or
+/* Convert a character to a digit value in radix r, or
-1 if out of range */
-static int s_ch2val(char c, int r);
+STATIC int s_ch2val(char c, int r);
/* Convert a digit value to a character */
-static char s_val2ch(int v, int caps);
+STATIC char s_val2ch(int v, int caps);
/* Take 2's complement of a buffer in place */
-static void s_2comp(unsigned char *buf, int len);
+STATIC void s_2comp(unsigned char *buf, int len);
/* Convert a value to binary, ignoring sign. On input, *limpos is the
bound on how many bytes should be written to buf; on output, *limpos
is set to the number of bytes actually written. */
-static mp_result s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad);
+STATIC mp_result s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad);
#if DEBUG
/* Dump a representation of the mp_int to standard output */
@@ -340,8 +342,8 @@ mp_result mp_int_init(mp_int z)
mp_int mp_int_alloc(void)
{
mp_int out = malloc(sizeof(mpz_t));
-
- if(out != NULL)
+
+ if(out != NULL)
mp_int_init(out);
return out;
@@ -357,11 +359,11 @@ mp_result mp_int_init_size(mp_int z, mp_size prec)
if(prec == 0)
prec = default_precision;
- else if(prec == 1)
+ else if(prec == 1)
return mp_int_init(z);
- else
+ else
prec = (mp_size) ROUND_PREC(prec);
-
+
if((MP_DIGITS(z) = s_alloc(prec)) == NULL)
return MP_MEMORY;
@@ -369,7 +371,7 @@ mp_result mp_int_init_size(mp_int z, mp_size prec)
MP_USED(z) = 1;
MP_ALLOC(z) = prec;
MP_SIGN(z) = MP_ZPOS;
-
+
return MP_OK;
}
@@ -550,17 +552,18 @@ mp_result mp_int_neg(mp_int a, mp_int c)
/* {{{ mp_int_add(a, b, c) */
mp_result mp_int_add(mp_int a, mp_int b, mp_int c)
-{
- mp_size ua, ub, uc, max;
+{
+ mp_size ua, ub, max;
CHECK(a != NULL && b != NULL && c != NULL);
- ua = MP_USED(a); ub = MP_USED(b); uc = MP_USED(c);
+ ua = MP_USED(a); ub = MP_USED(b);
max = MAX(ua, ub);
if(MP_SIGN(a) == MP_SIGN(b)) {
/* Same sign -- add magnitudes, preserve sign of addends */
mp_digit carry;
+ mp_size uc;
if(!s_pad(c, max))
return MP_MEMORY;
@@ -579,7 +582,7 @@ mp_result mp_int_add(mp_int a, mp_int b, mp_int c)
MP_USED(c) = uc;
MP_SIGN(c) = MP_SIGN(a);
- }
+ }
else {
/* Different signs -- subtract magnitudes, preserve sign of greater */
mp_int x, y;
@@ -606,7 +609,7 @@ mp_result mp_int_add(mp_int a, mp_int b, mp_int c)
s_usub(MP_DIGITS(x), MP_DIGITS(y), MP_DIGITS(c), MP_USED(x), MP_USED(y));
MP_USED(c) = MP_USED(x);
CLAMP(c);
-
+
/* Give result the sign of the larger */
MP_SIGN(c) = MP_SIGN(x);
}
@@ -634,16 +637,17 @@ mp_result mp_int_add_value(mp_int a, mp_small value, mp_int c)
mp_result mp_int_sub(mp_int a, mp_int b, mp_int c)
{
- mp_size ua, ub, uc, max;
+ mp_size ua, ub, max;
CHECK(a != NULL && b != NULL && c != NULL);
- ua = MP_USED(a); ub = MP_USED(b); uc = MP_USED(c);
+ ua = MP_USED(a); ub = MP_USED(b);
max = MAX(ua, ub);
if(MP_SIGN(a) != MP_SIGN(b)) {
/* Different signs -- add magnitudes and keep sign of a */
mp_digit carry;
+ mp_size uc;
if(!s_pad(c, max))
return MP_MEMORY;
@@ -662,7 +666,7 @@ mp_result mp_int_sub(mp_int a, mp_int b, mp_int c)
MP_USED(c) = uc;
MP_SIGN(c) = MP_SIGN(a);
- }
+ }
else {
/* Same signs -- subtract magnitudes */
mp_int x, y;
@@ -674,7 +678,7 @@ mp_result mp_int_sub(mp_int a, mp_int b, mp_int c)
if(cmp >= 0) {
x = a; y = b; osign = MP_ZPOS;
- }
+ }
else {
x = b; y = a; osign = MP_NEG;
}
@@ -711,7 +715,7 @@ mp_result mp_int_sub_value(mp_int a, mp_small value, mp_int c)
/* {{{ mp_int_mul(a, b, c) */
mp_result mp_int_mul(mp_int a, mp_int b, mp_int c)
-{
+{
mp_digit *out;
mp_size osize, ua, ub, p = 0;
mp_sign osign;
@@ -723,7 +727,7 @@ mp_result mp_int_mul(mp_int a, mp_int b, mp_int c)
mp_int_zero(c);
return MP_OK;
}
-
+
/* Output is positive if inputs have same sign, otherwise negative */
osign = (MP_SIGN(a) == MP_SIGN(b)) ? MP_ZPOS : MP_NEG;
@@ -739,11 +743,11 @@ mp_result mp_int_mul(mp_int a, mp_int b, mp_int c)
if((out = s_alloc(p)) == NULL)
return MP_MEMORY;
- }
+ }
else {
if(!s_pad(c, osize))
return MP_MEMORY;
-
+
out = MP_DIGITS(c);
}
ZERO(out, osize);
@@ -764,7 +768,7 @@ mp_result mp_int_mul(mp_int a, mp_int b, mp_int c)
MP_USED(c) = osize; /* might not be true, but we'll fix it ... */
CLAMP(c); /* ... right here */
MP_SIGN(c) = osign;
-
+
return MP_OK;
}
@@ -805,7 +809,7 @@ mp_result mp_int_mul_pow2(mp_int a, mp_small p2, mp_int c)
/* {{{ mp_int_sqr(a, c) */
mp_result mp_int_sqr(mp_int a, mp_int c)
-{
+{
mp_digit *out;
mp_size osize, p = 0;
@@ -819,9 +823,9 @@ mp_result mp_int_sqr(mp_int a, mp_int c)
if((out = s_alloc(p)) == NULL)
return MP_MEMORY;
- }
+ }
else {
- if(!s_pad(c, osize))
+ if(!s_pad(c, osize))
return MP_MEMORY;
out = MP_DIGITS(c);
@@ -843,7 +847,7 @@ mp_result mp_int_sqr(mp_int a, mp_int c)
MP_USED(c) = osize; /* might not be true, but we'll fix it ... */
CLAMP(c); /* ... right here */
MP_SIGN(c) = MP_ZPOS;
-
+
return MP_OK;
}
@@ -860,7 +864,7 @@ mp_result mp_int_div(mp_int a, mp_int b, mp_int q, mp_int r)
mp_sign sa = MP_SIGN(a), sb = MP_SIGN(b);
CHECK(a != NULL && b != NULL && q != r);
-
+
if(CMPZ(b) == 0)
return MP_UNDEF;
else if((cmp = s_ucmp(a, b)) < 0) {
@@ -874,7 +878,7 @@ mp_result mp_int_div(mp_int a, mp_int b, mp_int q, mp_int r)
mp_int_zero(q);
return MP_OK;
- }
+ }
else if(cmp == 0) {
/* If |a| = |b|, no division is required:
q = 1 or -1, r = 0
@@ -891,19 +895,19 @@ mp_result mp_int_div(mp_int a, mp_int b, mp_int q, mp_int r)
}
return MP_OK;
- }
+ }
/* When |a| > |b|, real division is required. We need someplace to
store quotient and remainder, but q and r are allowed to be NULL
or to overlap with the inputs.
*/
if((lg = s_isp2(b)) < 0) {
- if(q && b != q) {
+ if(q && b != q) {
if((res = mp_int_copy(a, q)) != MP_OK)
goto CLEANUP;
else
qout = q;
- }
+ }
else {
qout = TEMP(last);
SETUP(mp_int_init_copy(TEMP(last), a), last);
@@ -914,14 +918,14 @@ mp_result mp_int_div(mp_int a, mp_int b, mp_int q, mp_int r)
goto CLEANUP;
else
rout = r;
- }
+ }
else {
rout = TEMP(last);
SETUP(mp_int_init_copy(TEMP(last), b), last);
}
if((res = s_udiv(qout, rout)) != MP_OK) goto CLEANUP;
- }
+ }
else {
if(q && (res = mp_int_copy(a, q)) != MP_OK) goto CLEANUP;
if(r && (res = mp_int_copy(a, r)) != MP_OK) goto CLEANUP;
@@ -931,7 +935,7 @@ mp_result mp_int_div(mp_int a, mp_int b, mp_int q, mp_int r)
}
/* Recompute signs for output */
- if(rout) {
+ if(rout) {
MP_SIGN(rout) = sa;
if(CMPZ(rout) == 0)
MP_SIGN(rout) = MP_ZPOS;
@@ -965,7 +969,7 @@ mp_result mp_int_mod(mp_int a, mp_int m, mp_int c)
if(m == c) {
mp_int_init(&tmp);
out = &tmp;
- }
+ }
else {
out = c;
}
@@ -1021,7 +1025,7 @@ mp_result mp_int_div_pow2(mp_int a, mp_small p2, mp_int q, mp_int r)
if(q != NULL && (res = mp_int_copy(a, q)) == MP_OK)
s_qdiv(q, (mp_size) p2);
-
+
if(res == MP_OK && r != NULL && (res = mp_int_copy(a, r)) == MP_OK)
s_qmod(r, (mp_size) p2);
@@ -1037,7 +1041,7 @@ mp_result mp_int_expt(mp_int a, mp_small b, mp_int c)
mpz_t t;
mp_result res;
unsigned int v = abs(b);
-
+
CHECK(b >= 0 && c != NULL);
if((res = mp_int_init_copy(&t, a)) != MP_OK)
@@ -1056,7 +1060,7 @@ mp_result mp_int_expt(mp_int a, mp_small b, mp_int c)
if((res = mp_int_sqr(&t, &t)) != MP_OK)
goto CLEANUP;
}
-
+
CLEANUP:
mp_int_clear(&t);
return res;
@@ -1071,7 +1075,7 @@ mp_result mp_int_expt_value(mp_small a, mp_small b, mp_int c)
mpz_t t;
mp_result res;
unsigned int v = abs(b);
-
+
CHECK(b >= 0 && c != NULL);
if((res = mp_int_init_value(&t, a)) != MP_OK)
@@ -1090,7 +1094,7 @@ mp_result mp_int_expt_value(mp_small a, mp_small b, mp_int c)
if((res = mp_int_sqr(&t, &t)) != MP_OK)
goto CLEANUP;
}
-
+
CLEANUP:
mp_int_clear(&t);
return res;
@@ -1101,7 +1105,7 @@ mp_result mp_int_expt_value(mp_small a, mp_small b, mp_int c)
/* {{{ mp_int_compare(a, b) */
int mp_int_compare(mp_int a, mp_int b)
-{
+{
mp_sign sa;
CHECK(a != NULL && b != NULL);
@@ -1112,12 +1116,12 @@ int mp_int_compare(mp_int a, mp_int b)
/* If they're both zero or positive, the normal comparison
applies; if both negative, the sense is reversed. */
- if(sa == MP_ZPOS)
+ if(sa == MP_ZPOS)
return cmp;
else
return -cmp;
- }
+ }
else {
if(sa == MP_ZPOS)
return 1;
@@ -1131,7 +1135,7 @@ int mp_int_compare(mp_int a, mp_int b)
/* {{{ mp_int_compare_unsigned(a, b) */
int mp_int_compare_unsigned(mp_int a, mp_int b)
-{
+{
NRCHECK(a != NULL && b != NULL);
return s_ucmp(a, b);
@@ -1142,14 +1146,14 @@ int mp_int_compare_unsigned(mp_int a, mp_int b)
/* {{{ mp_int_compare_zero(z) */
int mp_int_compare_zero(mp_int z)
-{
+{
NRCHECK(z != NULL);
if(MP_USED(z) == 1 && z->digits[0] == 0)
return 0;
else if(MP_SIGN(z) == MP_ZPOS)
return 1;
- else
+ else
return -1;
}
@@ -1171,7 +1175,7 @@ int mp_int_compare_value(mp_int z, mp_small value)
return cmp;
else
return -cmp;
- }
+ }
else {
if(value < 0)
return 1;
@@ -1185,7 +1189,7 @@ int mp_int_compare_value(mp_int z, mp_small value)
/* {{{ mp_int_exptmod(a, b, m, c) */
mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m, mp_int c)
-{
+{
mp_result res;
mp_size um;
mpz_t temp[3];
@@ -1207,11 +1211,11 @@ mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m, mp_int c)
if(c == b || c == m) {
SETUP(mp_int_init_size(TEMP(2), 2 * um), last);
s = TEMP(2);
- }
+ }
else {
s = c;
}
-
+
if((res = mp_int_mod(a, m, TEMP(0))) != MP_OK) goto CLEANUP;
if((res = s_brmu(TEMP(1), m)) != MP_OK) goto CLEANUP;
@@ -1283,11 +1287,11 @@ mp_result mp_int_exptmod_known(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c
if(c == b || c == m) {
SETUP(mp_int_init_size(TEMP(1), 2 * um), last);
s = TEMP(1);
- }
+ }
else {
s = c;
}
-
+
if((res = mp_int_mod(a, m, TEMP(0))) != MP_OK) goto CLEANUP;
if((res = s_embar(TEMP(0), b, m, mu, s)) != MP_OK)
@@ -1334,7 +1338,7 @@ mp_result mp_int_invmod(mp_int a, mp_int m, mp_int c)
for(last = 0; last < 2; ++last)
mp_int_init(TEMP(last));
- if((res = mp_int_egcd(a, m, TEMP(0), TEMP(1), NULL)) != MP_OK)
+ if((res = mp_int_egcd(a, m, TEMP(0), TEMP(1), NULL)) != MP_OK)
goto CLEANUP;
if(mp_int_compare_value(TEMP(0), 1) != 0) {
@@ -1369,7 +1373,7 @@ mp_result mp_int_invmod(mp_int a, mp_int m, mp_int c)
/* Binary GCD algorithm due to Josef Stein, 1961 */
mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c)
-{
+{
int ca, cb, k = 0;
mpz_t u, v, t;
mp_result res;
@@ -1380,9 +1384,9 @@ mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c)
cb = CMPZ(b);
if(ca == 0 && cb == 0)
return MP_UNDEF;
- else if(ca == 0)
+ else if(ca == 0)
return mp_int_abs(b, c);
- else if(cb == 0)
+ else if(cb == 0)
return mp_int_abs(a, c);
mp_int_init(&t);
@@ -1395,16 +1399,16 @@ mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c)
{ /* Divide out common factors of 2 from u and v */
int div2_u = s_dp2k(&u), div2_v = s_dp2k(&v);
-
+
k = MIN(div2_u, div2_v);
s_qdiv(&u, (mp_size) k);
s_qdiv(&v, (mp_size) k);
}
-
+
if(mp_int_is_odd(&u)) {
if((res = mp_int_neg(&v, &t)) != MP_OK)
goto CLEANUP;
- }
+ }
else {
if((res = mp_int_copy(&u, &t)) != MP_OK)
goto CLEANUP;
@@ -1416,7 +1420,7 @@ mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c)
if(CMPZ(&t) > 0) {
if((res = mp_int_copy(&t, &u)) != MP_OK)
goto CLEANUP;
- }
+ }
else {
if((res = mp_int_neg(&t, &v)) != MP_OK)
goto CLEANUP;
@@ -1427,13 +1431,13 @@ mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c)
if(CMPZ(&t) == 0)
break;
- }
+ }
if((res = mp_int_abs(&u, c)) != MP_OK)
goto CLEANUP;
if(!s_qmul(c, (mp_size) k))
res = MP_MEMORY;
-
+
CLEANUP:
mp_int_clear(&v);
V: mp_int_clear(&u);
@@ -1450,14 +1454,14 @@ mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c)
of the elementary matrix operations as we go, so we can get values
x and y satisfying c = ax + by.
*/
-mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c,
+mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c,
mp_int x, mp_int y)
-{
+{
int k, last = 0, ca, cb;
mpz_t temp[8];
mp_result res;
-
- CHECK(a != NULL && b != NULL && c != NULL &&
+
+ CHECK(a != NULL && b != NULL && c != NULL &&
(x != NULL || y != NULL));
ca = CMPZ(a);
@@ -1467,7 +1471,7 @@ mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c,
else if(ca == 0) {
if((res = mp_int_abs(b, c)) != MP_OK) return res;
mp_int_zero(x); (void) mp_int_set_value(y, 1); return MP_OK;
- }
+ }
else if(cb == 0) {
if((res = mp_int_abs(a, c)) != MP_OK) return res;
(void) mp_int_set_value(x, 1); mp_int_zero(y); return MP_OK;
@@ -1475,7 +1479,7 @@ mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c,
/* Initialize temporaries:
A:0, B:1, C:2, D:3, u:4, v:5, ou:6, ov:7 */
- for(last = 0; last < 4; ++last)
+ for(last = 0; last < 4; ++last)
mp_int_init(TEMP(last));
TEMP(0)->digits[0] = 1;
TEMP(3)->digits[0] = 1;
@@ -1489,7 +1493,7 @@ mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c,
{ /* Divide out common factors of 2 from u and v */
int div2_u = s_dp2k(TEMP(4)), div2_v = s_dp2k(TEMP(5));
-
+
k = MIN(div2_u, div2_v);
s_qdiv(TEMP(4), k);
s_qdiv(TEMP(5), k);
@@ -1501,25 +1505,25 @@ mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c,
for(;;) {
while(mp_int_is_even(TEMP(4))) {
s_qdiv(TEMP(4), 1);
-
+
if(mp_int_is_odd(TEMP(0)) || mp_int_is_odd(TEMP(1))) {
- if((res = mp_int_add(TEMP(0), TEMP(7), TEMP(0))) != MP_OK)
+ if((res = mp_int_add(TEMP(0), TEMP(7), TEMP(0))) != MP_OK)
goto CLEANUP;
- if((res = mp_int_sub(TEMP(1), TEMP(6), TEMP(1))) != MP_OK)
+ if((res = mp_int_sub(TEMP(1), TEMP(6), TEMP(1))) != MP_OK)
goto CLEANUP;
}
s_qdiv(TEMP(0), 1);
s_qdiv(TEMP(1), 1);
}
-
+
while(mp_int_is_even(TEMP(5))) {
s_qdiv(TEMP(5), 1);
if(mp_int_is_odd(TEMP(2)) || mp_int_is_odd(TEMP(3))) {
- if((res = mp_int_add(TEMP(2), TEMP(7), TEMP(2))) != MP_OK)
+ if((res = mp_int_add(TEMP(2), TEMP(7), TEMP(2))) != MP_OK)
goto CLEANUP;
- if((res = mp_int_sub(TEMP(3), TEMP(6), TEMP(3))) != MP_OK)
+ if((res = mp_int_sub(TEMP(3), TEMP(6), TEMP(3))) != MP_OK)
goto CLEANUP;
}
@@ -1531,7 +1535,7 @@ mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c,
if((res = mp_int_sub(TEMP(4), TEMP(5), TEMP(4))) != MP_OK) goto CLEANUP;
if((res = mp_int_sub(TEMP(0), TEMP(2), TEMP(0))) != MP_OK) goto CLEANUP;
if((res = mp_int_sub(TEMP(1), TEMP(3), TEMP(1))) != MP_OK) goto CLEANUP;
- }
+ }
else {
if((res = mp_int_sub(TEMP(5), TEMP(4), TEMP(5))) != MP_OK) goto CLEANUP;
if((res = mp_int_sub(TEMP(2), TEMP(0), TEMP(2))) != MP_OK) goto CLEANUP;
@@ -1546,7 +1550,7 @@ mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c,
res = MP_MEMORY;
goto CLEANUP;
}
-
+
res = mp_int_copy(TEMP(5), c);
}
@@ -1572,8 +1576,8 @@ mp_result mp_int_lcm(mp_int a, mp_int b, mp_int c)
CHECK(a != NULL && b != NULL && c != NULL);
- /* Since a * b = gcd(a, b) * lcm(a, b), we can compute
- lcm(a, b) = (a / gcd(a, b)) * b.
+ /* Since a * b = gcd(a, b) * lcm(a, b), we can compute
+ lcm(a, b) = (a / gcd(a, b)) * b.
This formulation insures everything works even if the input
variables share space.
@@ -1681,7 +1685,7 @@ mp_result mp_int_root(mp_int a, mp_small b, mp_int c)
if((res = mp_int_copy(TEMP(4), TEMP(1))) != MP_OK)
goto CLEANUP;
}
-
+
if((res = mp_int_copy(TEMP(1), c)) != MP_OK)
goto CLEANUP;
@@ -1693,7 +1697,7 @@ mp_result mp_int_root(mp_int a, mp_small b, mp_int c)
while(--last >= 0)
mp_int_clear(TEMP(last));
- return res;
+ return res;
}
/* }}} */
@@ -1714,10 +1718,10 @@ mp_result mp_int_to_int(mp_int z, mp_small *out)
if((sz == MP_ZPOS && mp_int_compare_value(z, MP_SMALL_MAX) > 0) ||
mp_int_compare_value(z, MP_SMALL_MIN) < 0)
return MP_RANGE;
-
+
uz = MP_USED(z);
dz = MP_DIGITS(z) + uz - 1;
-
+
while(uz > 0) {
uv <<= MP_DIGIT_BIT/2;
uv = (uv << (MP_DIGIT_BIT/2)) | *dz--;
@@ -1740,26 +1744,26 @@ mp_result mp_int_to_uint(mp_int z, mp_usmall *out)
mp_size uz;
mp_digit *dz;
mp_sign sz;
-
+
CHECK(z != NULL);
/* Make sure the value is representable as an int */
sz = MP_SIGN(z);
if(!(sz == MP_ZPOS && mp_int_compare_value(z, UINT_MAX) <= 0))
return MP_RANGE;
-
+
uz = MP_USED(z);
dz = MP_DIGITS(z) + uz - 1;
-
+
while(uz > 0) {
uv <<= MP_DIGIT_BIT/2;
uv = (uv << (MP_DIGIT_BIT/2)) | *dz--;
--uz;
}
-
+
if(out)
*out = uv;
-
+
return MP_OK;
}
@@ -1767,7 +1771,7 @@ mp_result mp_int_to_uint(mp_int z, mp_usmall *out)
/* {{{ mp_int_to_string(z, radix, str, limit) */
-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)
{
mp_result res;
@@ -1780,7 +1784,7 @@ mp_result mp_int_to_string(mp_int z, mp_size radix,
if(CMPZ(z) == 0) {
*str++ = s_val2ch(0, 1);
- }
+ }
else {
mpz_t tmp;
char *h, *t;
@@ -1828,7 +1832,7 @@ mp_result mp_int_to_string(mp_int z, mp_size radix,
/* {{{ mp_int_string_len(z, radix) */
mp_result mp_int_string_len(mp_int z, mp_size radix)
-{
+{
int len;
CHECK(z != NULL);
@@ -1861,7 +1865,7 @@ mp_result mp_int_read_string(mp_int z, mp_size radix, const char *str)
/* {{{ mp_int_read_cstring(z, radix, *str, **end) */
mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str, char **end)
-{
+{
int ch;
CHECK(z != NULL && str != NULL);
@@ -1887,7 +1891,7 @@ mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str, char **e
}
/* Skip leading zeroes */
- while((ch = s_ch2val(*str, radix)) == 0)
+ while((ch = s_ch2val(*str, radix)) == 0)
++str;
/* Make sure there is enough space for the value */
@@ -1901,20 +1905,20 @@ mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str, char **e
s_dadd(z, (mp_digit)ch);
++str;
}
-
+
CLAMP(z);
/* Override sign for zero, even if negative specified. */
if(CMPZ(z) == 0)
MP_SIGN(z) = MP_ZPOS;
-
+
if(end != NULL)
*end = (char *)str;
/* Return a truncation error if the string has unprocessed
characters remaining, so the caller can tell if the whole string
was done */
- if(*str != '\0')
+ if(*str != '\0')
return MP_TRUNC;
else
return MP_OK;
@@ -1959,7 +1963,7 @@ mp_result mp_int_to_binary(mp_int z, unsigned char *buf, int limit)
int limpos = limit;
CHECK(z != NULL && buf != NULL);
-
+
res = s_tobin(z, buf, &limpos, PAD_FOR_2C);
if(MP_SIGN(z) == MP_NEG)
@@ -1993,7 +1997,7 @@ mp_result mp_int_read_binary(mp_int z, unsigned char *buf, int len)
MP_SIGN(z) = MP_NEG;
s_2comp(buf, len);
}
-
+
dz = MP_DIGITS(z);
for(tmp = buf, i = len; i > 0; --i, ++tmp) {
s_qmul(z, (mp_size) CHAR_BIT);
@@ -2014,7 +2018,7 @@ mp_result mp_int_read_binary(mp_int z, unsigned char *buf, int len)
mp_result mp_int_binary_len(mp_int z)
{
mp_result res = mp_int_count_bits(z);
- int bytes = mp_int_unsigned_len(z);
+ int bytes;
if(res <= 0)
return res;
@@ -2115,7 +2119,7 @@ const char *mp_error_string(mp_result res)
/* {{{ s_alloc(num) */
-static mp_digit *s_alloc(mp_size num)
+STATIC mp_digit *s_alloc(mp_size num)
{
mp_digit *out = malloc(num * sizeof(mp_digit));
@@ -2137,7 +2141,7 @@ static mp_digit *s_alloc(mp_size num)
/* {{{ s_realloc(old, osize, nsize) */
-static mp_digit *s_realloc(mp_digit *old, mp_size osize, mp_size nsize)
+STATIC mp_digit *s_realloc(mp_digit *old, mp_size osize, mp_size nsize)
{
#if DEBUG > 1
mp_digit *new = s_alloc(nsize);
@@ -2159,7 +2163,7 @@ static mp_digit *s_realloc(mp_digit *old, mp_size osize, mp_size nsize)
/* {{{ s_free(ptr) */
-static void s_free(void *ptr)
+STATIC void s_free(void *ptr)
{
free(ptr);
}
@@ -2168,7 +2172,7 @@ static void s_free(void *ptr)
/* {{{ s_pad(z, min) */
-static int s_pad(mp_int z, mp_size min)
+STATIC int s_pad(mp_int z, mp_size min)
{
if(MP_ALLOC(z) < min) {
mp_size nsize = ROUND_PREC(min);
@@ -2182,7 +2186,7 @@ static int s_pad(mp_int z, mp_size min)
}
else if((tmp = s_realloc(MP_DIGITS(z), MP_ALLOC(z), nsize)) == NULL)
return 0;
-
+
MP_DIGITS(z) = tmp;
MP_ALLOC(z) = nsize;
}
@@ -2194,7 +2198,7 @@ static int s_pad(mp_int z, mp_size min)
/* {{{ s_fake(z, value, vbuf) */
-static void s_fake(mp_int z, mp_small value, mp_digit vbuf[])
+STATIC void s_fake(mp_int z, mp_small value, mp_digit vbuf[])
{
mp_size uv = (mp_size) s_vpack(value, vbuf);
@@ -2208,7 +2212,7 @@ static void s_fake(mp_int z, mp_small value, mp_digit vbuf[])
/* {{{ s_cdig(da, db, len) */
-static int s_cdig(mp_digit *da, mp_digit *db, mp_size len)
+STATIC int s_cdig(mp_digit *da, mp_digit *db, mp_size len)
{
mp_digit *dat = da + len - 1, *dbt = db + len - 1;
@@ -2226,11 +2230,11 @@ static int s_cdig(mp_digit *da, mp_digit *db, mp_size len)
/* {{{ s_vpack(v, t[]) */
-static int s_vpack(mp_small v, mp_digit t[])
+STATIC int s_vpack(mp_small v, mp_digit t[])
{
mp_usmall uv = (mp_usmall) ((v < 0) ? -v : v);
int ndig = 0;
-
+
if(uv == 0)
t[ndig++] = 0;
else {
@@ -2248,15 +2252,15 @@ static int s_vpack(mp_small v, mp_digit t[])
/* {{{ s_ucmp(a, b) */
-static int s_ucmp(mp_int a, mp_int b)
+STATIC int s_ucmp(mp_int a, mp_int b)
{
mp_size ua = MP_USED(a), ub = MP_USED(b);
-
+
if(ua > ub)
return 1;
- else if(ub > ua)
+ else if(ub > ua)
return -1;
- else
+ else
return s_cdig(MP_DIGITS(a), MP_DIGITS(b), ua);
}
@@ -2264,7 +2268,7 @@ static int s_ucmp(mp_int a, mp_int b)
/* {{{ s_vcmp(a, v) */
-static int s_vcmp(mp_int a, mp_small v)
+STATIC int s_vcmp(mp_int a, mp_small v)
{
mp_digit vdig[MP_VALUE_DIGITS(v)];
int ndig = 0;
@@ -2284,7 +2288,7 @@ static int s_vcmp(mp_int a, mp_small v)
/* {{{ s_uadd(da, db, dc, size_a, size_b) */
-static mp_digit s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc,
+STATIC mp_digit s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc,
mp_size size_a, mp_size size_b)
{
mp_size pos;
@@ -2319,7 +2323,7 @@ static mp_digit s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc,
/* {{{ s_usub(da, db, dc, size_a, size_b) */
-static void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc,
+STATIC void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc,
mp_size size_a, mp_size size_b)
{
mp_size pos;
@@ -2340,7 +2344,7 @@ static void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc,
/* Finish the subtraction for remaining upper digits of da */
for(/* */; pos < size_a; ++pos, ++da, ++dc) {
w = ((mp_word)MP_DIGIT_MAX + 1 + /* MP_RADIX */
- (mp_word)*da) - w;
+ (mp_word)*da) - w;
*dc = LOWER_HALF(w);
w = (UPPER_HALF(w) == 0);
@@ -2354,7 +2358,7 @@ static void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc,
/* {{{ s_kmul(da, db, dc, size_a, size_b) */
-static int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc,
+STATIC int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc,
mp_size size_a, mp_size size_b)
{
mp_size bot_size;
@@ -2374,13 +2378,13 @@ static int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc,
Karatsuba algorithm to compute the product; otherwise use the
normal multiplication algorithm
*/
- if(multiply_threshold &&
- size_a >= multiply_threshold &&
+ if(multiply_threshold &&
+ size_a >= multiply_threshold &&
size_b > bot_size) {
mp_digit *t1, *t2, *t3, carry;
- mp_digit *a_top = da + bot_size;
+ mp_digit *a_top = da + bot_size;
mp_digit *b_top = db + bot_size;
mp_size at_size = size_a - bot_size;
@@ -2389,7 +2393,7 @@ static int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc,
/* Do a single allocation for all three temporary buffers needed;
each buffer must be big enough to hold the product of two
- bottom halves, and one buffer needs space for the completed
+ bottom halves, and one buffer needs space for the completed
product; twice the space is plenty.
*/
if((t1 = s_alloc(4 * buf_size)) == NULL) return 0;
@@ -2423,15 +2427,15 @@ static int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc,
/* Assemble the output value */
COPY(t1, dc, buf_size);
carry = s_uadd(t3, dc + bot_size, dc + bot_size,
- buf_size + 1, buf_size);
+ buf_size + 1, buf_size);
assert(carry == 0);
-
+
carry = s_uadd(t2, dc + 2*bot_size, dc + 2*bot_size,
- buf_size, buf_size);
+ buf_size, buf_size);
assert(carry == 0);
-
+
s_free(t1); /* note t2 and t3 are just internal pointers to t1 */
- }
+ }
else {
s_umul(da, db, dc, size_a, size_b);
}
@@ -2443,7 +2447,7 @@ static int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc,
/* {{{ s_umul(da, db, dc, size_a, size_b) */
-static void s_umul(mp_digit *da, mp_digit *db, mp_digit *dc,
+STATIC void s_umul(mp_digit *da, mp_digit *db, mp_digit *dc,
mp_size size_a, mp_size size_b)
{
mp_size a, b;
@@ -2472,7 +2476,7 @@ static void s_umul(mp_digit *da, mp_digit *db, mp_digit *dc,
/* {{{ s_ksqr(da, dc, size_a) */
-static int s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a)
+STATIC int s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a)
{
if(multiply_threshold && size_a > multiply_threshold) {
mp_size bot_size = (size_a + 1) / 2;
@@ -2517,7 +2521,7 @@ static int s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a)
s_free(t1); /* note that t2 and t2 are internal pointers only */
- }
+ }
else {
s_usqr(da, dc, size_a);
}
@@ -2529,7 +2533,7 @@ static int s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a)
/* {{{ s_usqr(da, dc, size_a) */
-static void s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a)
+STATIC void s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a)
{
mp_size i, j;
mp_word w;
@@ -2571,7 +2575,7 @@ static void s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a)
}
w = w + *dct;
- *dct = (mp_digit)w;
+ *dct = (mp_digit)w;
while((w = UPPER_HALF(w)) != 0) {
++dct; w = w + *dct;
*dct = LOWER_HALF(w);
@@ -2585,7 +2589,7 @@ static void s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a)
/* {{{ s_dadd(a, b) */
-static void s_dadd(mp_int a, mp_digit b)
+STATIC void s_dadd(mp_int a, mp_digit b)
{
mp_word w = 0;
mp_digit *da = MP_DIGITS(a);
@@ -2612,7 +2616,7 @@ static void s_dadd(mp_int a, mp_digit b)
/* {{{ s_dmul(a, b) */
-static void s_dmul(mp_int a, mp_digit b)
+STATIC void s_dmul(mp_int a, mp_digit b)
{
mp_word w = 0;
mp_digit *da = MP_DIGITS(a);
@@ -2635,7 +2639,7 @@ static void s_dmul(mp_int a, mp_digit b)
/* {{{ s_dbmul(da, b, dc, size_a) */
-static void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, mp_size size_a)
+STATIC void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, mp_size size_a)
{
mp_word w = 0;
@@ -2655,23 +2659,23 @@ static void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, mp_size size_a)
/* {{{ s_ddiv(da, d, dc, size_a) */
-static mp_digit s_ddiv(mp_int a, mp_digit b)
+STATIC mp_digit s_ddiv(mp_int a, mp_digit b)
{
mp_word w = 0, qdigit;
mp_size ua = MP_USED(a);
mp_digit *da = MP_DIGITS(a) + ua - 1;
-
+
for(/* */; ua > 0; --ua, --da) {
w = (w << MP_DIGIT_BIT) | *da;
if(w >= b) {
qdigit = w / b;
w = w % b;
- }
+ }
else {
qdigit = 0;
}
-
+
*da = (mp_digit)qdigit;
}
@@ -2683,7 +2687,7 @@ static mp_digit s_ddiv(mp_int a, mp_digit b)
/* {{{ s_qdiv(z, p2) */
-static void s_qdiv(mp_int z, mp_size p2)
+STATIC void s_qdiv(mp_int z, mp_size p2)
{
mp_size ndig = p2 / MP_DIGIT_BIT, nbits = p2 % MP_DIGIT_BIT;
mp_size uz = MP_USED(z);
@@ -2699,7 +2703,7 @@ static void s_qdiv(mp_int z, mp_size p2)
to = MP_DIGITS(z); from = to + ndig;
- for(mark = ndig; mark < uz; ++mark)
+ for(mark = ndig; mark < uz; ++mark)
*to++ = *from++;
MP_USED(z) = uz - ndig;
@@ -2730,7 +2734,7 @@ static void s_qdiv(mp_int z, mp_size p2)
/* {{{ s_qmod(z, p2) */
-static void s_qmod(mp_int z, mp_size p2)
+STATIC void s_qmod(mp_int z, mp_size p2)
{
mp_size start = p2 / MP_DIGIT_BIT + 1, rest = p2 % MP_DIGIT_BIT;
mp_size uz = MP_USED(z);
@@ -2747,7 +2751,7 @@ static void s_qmod(mp_int z, mp_size p2)
/* {{{ s_qmul(z, p2) */
-static int s_qmul(mp_int z, mp_size p2)
+STATIC int s_qmul(mp_int z, mp_size p2)
{
mp_size uz, need, rest, extra, i;
mp_digit *from, *to, d;
@@ -2755,7 +2759,7 @@ static int s_qmul(mp_int z, mp_size p2)
if(p2 == 0)
return 1;
- uz = MP_USED(z);
+ uz = MP_USED(z);
need = p2 / MP_DIGIT_BIT; rest = p2 % MP_DIGIT_BIT;
/* Figure out if we need an extra digit at the top end; this occurs
@@ -2790,7 +2794,7 @@ static int s_qmul(mp_int z, mp_size p2)
d = 0;
for(i = need, from = MP_DIGITS(z) + need; i < uz; ++i, ++from) {
mp_digit save = *from;
-
+
*from = (*from << rest) | (d >> (MP_DIGIT_BIT - rest));
d = save;
}
@@ -2815,7 +2819,7 @@ static int s_qmul(mp_int z, mp_size p2)
/* Compute z = 2^p2 - |z|; requires that 2^p2 >= |z|
The sign of the result is always zero/positive.
*/
-static int s_qsub(mp_int z, mp_size p2)
+STATIC int s_qsub(mp_int z, mp_size p2)
{
mp_digit hi = (1 << (p2 % MP_DIGIT_BIT)), *zp;
mp_size tdig = (p2 / MP_DIGIT_BIT), pos;
@@ -2835,7 +2839,7 @@ static int s_qsub(mp_int z, mp_size p2)
*zp = LOWER_HALF(w);
assert(UPPER_HALF(w) != 0); /* no borrow out should be possible */
-
+
MP_SIGN(z) = MP_ZPOS;
CLAMP(z);
@@ -2846,7 +2850,7 @@ static int s_qsub(mp_int z, mp_size p2)
/* {{{ s_dp2k(z) */
-static int s_dp2k(mp_int z)
+STATIC int s_dp2k(mp_int z)
{
int k = 0;
mp_digit *dp = MP_DIGITS(z), d;
@@ -2858,7 +2862,7 @@ static int s_dp2k(mp_int z)
k += MP_DIGIT_BIT;
++dp;
}
-
+
d = *dp;
while((d & 1) == 0) {
d >>= 1;
@@ -2872,7 +2876,7 @@ static int s_dp2k(mp_int z)
/* {{{ s_isp2(z) */
-static int s_isp2(mp_int z)
+STATIC int s_isp2(mp_int z)
{
mp_size uz = MP_USED(z), k = 0;
mp_digit *dz = MP_DIGITS(z), d;
@@ -2898,7 +2902,7 @@ static int s_isp2(mp_int z)
/* {{{ s_2expt(z, k) */
-static int s_2expt(mp_int z, mp_small k)
+STATIC int s_2expt(mp_int z, mp_small k)
{
mp_size ndig, rest;
mp_digit *dz;
@@ -2921,7 +2925,7 @@ static int s_2expt(mp_int z, mp_small k)
/* {{{ s_norm(a, b) */
-static int s_norm(mp_int a, mp_int b)
+STATIC int s_norm(mp_int a, mp_int b)
{
mp_digit d = b->digits[MP_USED(b) - 1];
int k = 0;
@@ -2944,7 +2948,7 @@ static int s_norm(mp_int a, mp_int b)
/* {{{ s_brmu(z, m) */
-static mp_result s_brmu(mp_int z, mp_int m)
+STATIC mp_result s_brmu(mp_int z, mp_int m)
{
mp_size um = MP_USED(m) * 2;
@@ -2959,7 +2963,7 @@ static mp_result s_brmu(mp_int z, mp_int m)
/* {{{ s_reduce(x, m, mu, q1, q2) */
-static int s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2)
+STATIC int s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2)
{
mp_size um = MP_USED(m), umb_p1, umb_m1;
@@ -3008,10 +3012,10 @@ static int s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2)
/* Perform modular exponentiation using Barrett's method, where mu is
the reduction constant for m. Assumes a < m, b > 0. */
-static mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c)
+STATIC mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c)
{
mp_digit *db, *dbt, umu, d;
- mpz_t temp[3];
+ mpz_t temp[3];
mp_result res;
int last = 0;
@@ -3063,7 +3067,7 @@ static mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c)
}
mp_int_copy(TEMP(0), c);
}
-
+
d >>= 1;
if(!d) break;
@@ -3077,7 +3081,7 @@ static mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c)
CLEANUP:
while(--last >= 0)
mp_int_clear(TEMP(last));
-
+
return res;
}
@@ -3088,7 +3092,7 @@ static mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c)
/* Precondition: a >= b and b > 0
Postcondition: a' = a / b, b' = a % b
*/
-static mp_result s_udiv(mp_int a, mp_int b)
+STATIC mp_result s_udiv(mp_int a, mp_int b)
{
mpz_t q, r, t;
mp_size ua, ub, qpos = 0;
@@ -3121,16 +3125,16 @@ static mp_result s_udiv(mp_int a, mp_int b)
if(s_ucmp(b, &r) > 0) {
r.digits -= 1;
r.used += 1;
-
- if(++skip > 1 && qpos > 0)
+
+ if(++skip > 1 && qpos > 0)
q.digits[qpos++] = 0;
-
+
CLAMP(&r);
}
else {
mp_word pfx = r.digits[r.used - 1];
mp_word qdigit;
-
+
if(r.used > 1 && pfx <= btop) {
pfx <<= MP_DIGIT_BIT / 2;
pfx <<= MP_DIGIT_BIT / 2;
@@ -3139,22 +3143,19 @@ static mp_result s_udiv(mp_int a, mp_int b)
qdigit = pfx / btop;
if(qdigit > MP_DIGIT_MAX) {
- if(qdigit & MP_DIGIT_MAX)
- qdigit = MP_DIGIT_MAX;
- else
- qdigit = 1;
+ qdigit = MP_DIGIT_MAX;
}
-
+
s_dbmul(MP_DIGITS(b), (mp_digit) qdigit, t.digits, ub);
t.used = ub + 1; CLAMP(&t);
while(s_ucmp(&t, &r) > 0) {
--qdigit;
(void) mp_int_sub(&t, b, &t); /* cannot fail */
}
-
+
s_usub(r.digits, t.digits, r.digits, r.used, t.used);
CLAMP(&r);
-
+
q.digits[qpos++] = (mp_digit) qdigit;
ZERO(t.digits, t.used);
skip = 0;
@@ -3170,10 +3171,10 @@ static mp_result s_udiv(mp_int a, mp_int b)
CLAMP(a);
if(k != 0)
s_qdiv(a, k);
-
+
mp_int_copy(a, b); /* ok: 0 <= r < b */
mp_int_copy(&q, a); /* ok: q <= a */
-
+
mp_int_clear(&t);
CLEANUP:
mp_int_clear(&q);
@@ -3184,7 +3185,7 @@ static mp_result s_udiv(mp_int a, mp_int b)
/* {{{ s_outlen(z, r) */
-static int s_outlen(mp_int z, mp_size r)
+STATIC int s_outlen(mp_int z, mp_size r)
{
mp_result bits;
double raw;
@@ -3201,7 +3202,7 @@ static int s_outlen(mp_int z, mp_size r)
/* {{{ s_inlen(len, r) */
-static mp_size s_inlen(int len, mp_size r)
+STATIC mp_size s_inlen(int len, mp_size r)
{
double raw = (double)len / s_log2[r];
mp_size bits = (mp_size)(raw + 0.5);
@@ -3213,7 +3214,7 @@ static mp_size s_inlen(int len, mp_size r)
/* {{{ s_ch2val(c, r) */
-static int s_ch2val(char c, int r)
+STATIC int s_ch2val(char c, int r)
{
int out;
@@ -3231,7 +3232,7 @@ static int s_ch2val(char c, int r)
/* {{{ s_val2ch(v, caps) */
-static char s_val2ch(int v, int caps)
+STATIC char s_val2ch(int v, int caps)
{
assert(v >= 0);
@@ -3251,7 +3252,7 @@ static char s_val2ch(int v, int caps)
/* {{{ s_2comp(buf, len) */
-static void s_2comp(unsigned char *buf, int len)
+STATIC void s_2comp(unsigned char *buf, int len)
{
int i;
unsigned short s = 1;
@@ -3273,7 +3274,7 @@ static void s_2comp(unsigned char *buf, int len)
/* {{{ s_tobin(z, buf, *limpos) */
-static mp_result s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad)
+STATIC mp_result s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad)
{
mp_size uz;
mp_digit *dz;
@@ -3340,7 +3341,7 @@ void s_print_buf(char *tag, mp_digit *buf, mp_size num)
fprintf(stderr, "%s: ", tag);
- for(i = num - 1; i >= 0; --i)
+ for(i = num - 1; i >= 0; --i)
fprintf(stderr, "%0*X", (int)(MP_DIGIT_BIT / 4), buf[i]);
fputc('\n', stderr);
diff --git a/source4/heimdal/lib/hcrypto/imath/imath.h b/source4/heimdal/lib/hcrypto/imath/imath.h
index 62b51c8fd8..cb877959e9 100644
--- a/source4/heimdal/lib/hcrypto/imath/imath.h
+++ b/source4/heimdal/lib/hcrypto/imath/imath.h
@@ -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 */
diff --git a/source4/heimdal/lib/hcrypto/rc4.c b/source4/heimdal/lib/hcrypto/rc4.c
index 81cf093e4d..988c42424e 100644
--- a/source4/heimdal/lib/hcrypto/rc4.c
+++ b/source4/heimdal/lib/hcrypto/rc4.c
@@ -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;
diff --git a/source4/heimdal/lib/hcrypto/rc4.h b/source4/heimdal/lib/hcrypto/rc4.h
index 4633655786..f93482f4d1 100644
--- a/source4/heimdal/lib/hcrypto/rc4.h
+++ b/source4/heimdal/lib/hcrypto/rc4.h
@@ -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 *);
diff --git a/source4/heimdal/lib/hcrypto/rsa-imath.c b/source4/heimdal/lib/hcrypto/rsa-imath.c
index 2641dc1bc4..a2b9d2a678 100644
--- a/source4/heimdal/lib/hcrypto/rsa-imath.c
+++ b/source4/heimdal/lib/hcrypto/rsa-imath.c
@@ -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);
diff --git a/source4/heimdal/lib/hcrypto/rsa.c b/source4/heimdal/lib/hcrypto/rsa.c
index 9b9ecea674..6a883454a3 100644
--- a/source4/heimdal/lib/hcrypto/rsa.c
+++ b/source4/heimdal/lib/hcrypto/rsa.c
@@ -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;
+}
diff --git a/source4/heimdal/lib/hcrypto/rsa.h b/source4/heimdal/lib/hcrypto/rsa.h
index 257e7f01c4..9354aaaa48 100644
--- a/source4/heimdal/lib/hcrypto/rsa.h
+++ b/source4/heimdal/lib/hcrypto/rsa.h
@@ -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 */
diff --git a/source4/heimdal/lib/hdb/dbinfo.c b/source4/heimdal/lib/hdb/dbinfo.c
index a399ab0a5c..5019016ed5 100644
--- a/source4/heimdal/lib/hdb/dbinfo.c
+++ b/source4/heimdal/lib/hdb/dbinfo.c
@@ -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);
diff --git a/source4/heimdal/lib/hdb/keytab.c b/source4/heimdal/lib/hdb/keytab.c
index 6cab8a44f0..925ff67c58 100644
--- a/source4/heimdal/lib/hdb/keytab.c
+++ b/source4/heimdal/lib/hdb/keytab.c
@@ -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);
diff --git a/source4/heimdal/lib/hx509/ca.c b/source4/heimdal/lib/hx509/ca.c
index 95f206f195..552a869809 100644
--- a/source4/heimdal/lib/hx509/ca.c
+++ b/source4/heimdal/lib/hx509/ca.c
@@ -1193,12 +1193,14 @@ ca_sign(hx509_context context,
unsigned char hash[SHA_DIGEST_LENGTH];
{
- SHA_CTX m;
-
- SHA1_Init(&m);
- SHA1_Update(&m, tbs->spki.subjectPublicKey.data,
- tbs->spki.subjectPublicKey.length / 8);
- SHA1_Final (hash, &m);
+ EVP_MD_CTX *ctx;
+
+ ctx = EVP_MD_CTX_create();
+ EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
+ EVP_DigestUpdate(ctx, tbs->spki.subjectPublicKey.data,
+ tbs->spki.subjectPublicKey.length / 8);
+ EVP_DigestFinal_ex(ctx, hash, NULL);
+ EVP_MD_CTX_destroy(ctx);
}
si.data = hash;
diff --git a/source4/heimdal/lib/hx509/cert.c b/source4/heimdal/lib/hx509/cert.c
index 7eda0eba48..7eaf6eb3c8 100644
--- a/source4/heimdal/lib/hx509/cert.c
+++ b/source4/heimdal/lib/hx509/cert.c
@@ -2243,7 +2243,8 @@ hx509_verify_path(hx509_context context,
*/
for (i = path.len - 1; i >= 0; i--) {
- Certificate *signer, *c;
+ hx509_cert signer;
+ Certificate *c;
c = _hx509_get_cert(path.val[i]);
@@ -2251,9 +2252,9 @@ hx509_verify_path(hx509_context context,
if (i + 1 == path.len) {
int selfsigned;
- signer = path.val[i]->data;
+ signer = path.val[i];
- ret = certificate_is_self_signed(context, signer, &selfsigned);
+ ret = certificate_is_self_signed(context, signer->data, &selfsigned);
if (ret)
goto out;
@@ -2262,7 +2263,7 @@ hx509_verify_path(hx509_context context,
continue;
} else {
/* take next certificate in chain */
- signer = path.val[i + 1]->data;
+ signer = path.val[i + 1];
}
/* verify signatureValue */
@@ -2326,10 +2327,32 @@ hx509_verify_signature(hx509_context context,
const heim_octet_string *data,
const heim_octet_string *sig)
{
- return _hx509_verify_signature(context, signer->data, alg, data, sig);
+ return _hx509_verify_signature(context, signer, alg, data, sig);
+}
+
+int
+_hx509_verify_signature_bitstring(hx509_context context,
+ const hx509_cert signer,
+ const AlgorithmIdentifier *alg,
+ const heim_octet_string *data,
+ const heim_bit_string *sig)
+{
+ heim_octet_string os;
+
+ if (sig->length & 7) {
+ hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
+ "signature not multiple of 8 bits");
+ return HX509_CRYPTO_SIG_INVALID_FORMAT;
+ }
+
+ os.data = sig->data;
+ os.length = sig->length / 8;
+
+ return _hx509_verify_signature(context, signer, alg, data, &os);
}
+
/**
* Verify that the certificate is allowed to be used for the hostname
* and address.
diff --git a/source4/heimdal/lib/hx509/crypto.c b/source4/heimdal/lib/hx509/crypto.c
index f4667c6e31..050a0902b3 100644
--- a/source4/heimdal/lib/hx509/crypto.c
+++ b/source4/heimdal/lib/hx509/crypto.c
@@ -97,6 +97,7 @@ struct signature_alg {
#define RA_RSA_USES_DIGEST_INFO 0x1000000
time_t best_before; /* refuse signature made after best before date */
+ const EVP_MD *(*evp_md)(void);
int (*verify_signature)(hx509_context context,
const struct signature_alg *,
const Certificate *,
@@ -549,32 +550,18 @@ rsa_verify_signature(hx509_context context,
int tosize, retsize;
int ret;
RSA *rsa;
- RSAPublicKey pk;
size_t size;
+ const unsigned char *p;
memset(&di, 0, sizeof(di));
spi = &signer->tbsCertificate.subjectPublicKeyInfo;
- rsa = RSA_new();
+ p = spi->subjectPublicKey.data;
+ size = spi->subjectPublicKey.length / 8;
+
+ rsa = d2i_RSAPublicKey(NULL, &p, size);
if (rsa == NULL) {
- hx509_set_error_string(context, 0, ENOMEM, "out of memory");
- return ENOMEM;
- }
- ret = decode_RSAPublicKey(spi->subjectPublicKey.data,
- spi->subjectPublicKey.length / 8,
- &pk, &size);
- if (ret) {
- hx509_set_error_string(context, 0, ret, "Failed to decode RSAPublicKey");
- goto out;
- }
-
- rsa->n = heim_int2BN(&pk.modulus);
- rsa->e = heim_int2BN(&pk.publicExponent);
-
- free_RSAPublicKey(&pk);
-
- if (rsa->n == NULL || rsa->e == NULL) {
ret = ENOMEM;
hx509_set_error_string(context, 0, ret, "out of memory");
goto out;
@@ -641,7 +628,7 @@ rsa_verify_signature(hx509_context context,
&di.digest);
} else {
if (retsize != data->length ||
- memcmp(to, data->data, retsize) != 0)
+ ct_memcmp(to, data->data, retsize) != 0)
{
ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
hx509_set_error_string(context, 0, ret, "RSA Signature incorrect");
@@ -649,10 +636,12 @@ rsa_verify_signature(hx509_context context,
}
free(to);
}
+ ret = 0;
out:
free_DigestInfo(&di);
- RSA_free(rsa);
+ if (rsa)
+ RSA_free(rsa);
return ret;
}
@@ -1130,39 +1119,8 @@ dsa_parse_private_key(hx509_context context,
}
#endif
-
-static int
-sha1_verify_signature(hx509_context context,
- const struct signature_alg *sig_alg,
- const Certificate *signer,
- const AlgorithmIdentifier *alg,
- const heim_octet_string *data,
- const heim_octet_string *sig)
-{
- unsigned char digest[SHA_DIGEST_LENGTH];
- SHA_CTX m;
-
- if (sig->length != SHA_DIGEST_LENGTH) {
- hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
- "SHA1 sigature have wrong length");
- return HX509_CRYPTO_SIG_INVALID_FORMAT;
- }
-
- SHA1_Init(&m);
- SHA1_Update(&m, data->data, data->length);
- SHA1_Final (digest, &m);
-
- if (memcmp(digest, sig->data, SHA_DIGEST_LENGTH) != 0) {
- hx509_set_error_string(context, 0, HX509_CRYPTO_BAD_SIGNATURE,
- "Bad SHA1 sigature");
- return HX509_CRYPTO_BAD_SIGNATURE;
- }
-
- return 0;
-}
-
static int
-sha256_create_signature(hx509_context context,
+evp_md_create_signature(hx509_context context,
const struct signature_alg *sig_alg,
const hx509_private_key signer,
const AlgorithmIdentifier *alg,
@@ -1170,7 +1128,8 @@ sha256_create_signature(hx509_context context,
AlgorithmIdentifier *signatureAlgorithm,
heim_octet_string *sig)
{
- SHA256_CTX m;
+ size_t sigsize = EVP_MD_size(sig_alg->evp_md());
+ EVP_MD_CTX *ctx;
memset(sig, 0, sizeof(*sig));
@@ -1183,140 +1142,50 @@ sha256_create_signature(hx509_context context,
}
- sig->data = malloc(SHA256_DIGEST_LENGTH);
+ sig->data = malloc(sigsize);
if (sig->data == NULL) {
sig->length = 0;
return ENOMEM;
}
- sig->length = SHA256_DIGEST_LENGTH;
+ sig->length = sigsize;
+
+ ctx = EVP_MD_CTX_create();
+ EVP_DigestInit_ex(ctx, sig_alg->evp_md(), NULL);
+ EVP_DigestUpdate(ctx, data->data, data->length);
+ EVP_DigestFinal_ex(ctx, sig->data, NULL);
+ EVP_MD_CTX_destroy(ctx);
- SHA256_Init(&m);
- SHA256_Update(&m, data->data, data->length);
- SHA256_Final (sig->data, &m);
return 0;
}
static int
-sha256_verify_signature(hx509_context context,
+evp_md_verify_signature(hx509_context context,
const struct signature_alg *sig_alg,
const Certificate *signer,
const AlgorithmIdentifier *alg,
const heim_octet_string *data,
const heim_octet_string *sig)
{
- unsigned char digest[SHA256_DIGEST_LENGTH];
- SHA256_CTX m;
+ unsigned char digest[EVP_MAX_MD_SIZE];
+ EVP_MD_CTX *ctx;
+ size_t sigsize = EVP_MD_size(sig_alg->evp_md());
- if (sig->length != SHA256_DIGEST_LENGTH) {
+ if (sig->length != sigsize || sigsize > sizeof(digest)) {
hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
"SHA256 sigature have wrong length");
return HX509_CRYPTO_SIG_INVALID_FORMAT;
}
- SHA256_Init(&m);
- SHA256_Update(&m, data->data, data->length);
- SHA256_Final (digest, &m);
-
- if (memcmp(digest, sig->data, SHA256_DIGEST_LENGTH) != 0) {
- hx509_set_error_string(context, 0, HX509_CRYPTO_BAD_SIGNATURE,
- "Bad SHA256 sigature");
- return HX509_CRYPTO_BAD_SIGNATURE;
- }
-
- return 0;
-}
-
-static int
-sha1_create_signature(hx509_context context,
- const struct signature_alg *sig_alg,
- const hx509_private_key signer,
- const AlgorithmIdentifier *alg,
- const heim_octet_string *data,
- AlgorithmIdentifier *signatureAlgorithm,
- heim_octet_string *sig)
-{
- SHA_CTX m;
-
- memset(sig, 0, sizeof(*sig));
-
- if (signatureAlgorithm) {
- int ret;
- ret = set_digest_alg(signatureAlgorithm, sig_alg->sig_oid,
- "\x05\x00", 2);
- if (ret)
- return ret;
- }
-
-
- sig->data = malloc(SHA_DIGEST_LENGTH);
- if (sig->data == NULL) {
- sig->length = 0;
- return ENOMEM;
- }
- sig->length = SHA_DIGEST_LENGTH;
-
- SHA1_Init(&m);
- SHA1_Update(&m, data->data, data->length);
- SHA1_Final (sig->data, &m);
+ ctx = EVP_MD_CTX_create();
+ EVP_DigestInit_ex(ctx, sig_alg->evp_md(), NULL);
+ EVP_DigestUpdate(ctx, data->data, data->length);
+ EVP_DigestFinal_ex(ctx, digest, NULL);
+ EVP_MD_CTX_destroy(ctx);
- return 0;
-}
-
-static int
-md5_verify_signature(hx509_context context,
- const struct signature_alg *sig_alg,
- const Certificate *signer,
- const AlgorithmIdentifier *alg,
- const heim_octet_string *data,
- const heim_octet_string *sig)
-{
- unsigned char digest[MD5_DIGEST_LENGTH];
- MD5_CTX m;
-
- if (sig->length != MD5_DIGEST_LENGTH) {
- hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
- "MD5 sigature have wrong length");
- return HX509_CRYPTO_SIG_INVALID_FORMAT;
- }
-
- MD5_Init(&m);
- MD5_Update(&m, data->data, data->length);
- MD5_Final (digest, &m);
-
- if (memcmp(digest, sig->data, MD5_DIGEST_LENGTH) != 0) {
- hx509_set_error_string(context, 0, HX509_CRYPTO_BAD_SIGNATURE,
- "Bad MD5 sigature");
- return HX509_CRYPTO_BAD_SIGNATURE;
- }
-
- return 0;
-}
-
-static int
-md2_verify_signature(hx509_context context,
- const struct signature_alg *sig_alg,
- const Certificate *signer,
- const AlgorithmIdentifier *alg,
- const heim_octet_string *data,
- const heim_octet_string *sig)
-{
- unsigned char digest[MD2_DIGEST_LENGTH];
- MD2_CTX m;
-
- if (sig->length != MD2_DIGEST_LENGTH) {
- hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
- "MD2 sigature have wrong length");
- return HX509_CRYPTO_SIG_INVALID_FORMAT;
- }
-
- MD2_Init(&m);
- MD2_Update(&m, data->data, data->length);
- MD2_Final (digest, &m);
-
- if (memcmp(digest, sig->data, MD2_DIGEST_LENGTH) != 0) {
+ if (ct_memcmp(digest, sig->data, sigsize) != 0) {
hx509_set_error_string(context, 0, HX509_CRYPTO_BAD_SIGNATURE,
- "Bad MD2 sigature");
+ "Bad %s sigature", sig_alg->name);
return HX509_CRYPTO_BAD_SIGNATURE;
}
@@ -1333,6 +1202,7 @@ static const struct signature_alg ecdsa_with_sha256_alg = {
&_hx509_signature_sha256_data,
PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
0,
+ NULL,
ecdsa_verify_signature,
ecdsa_create_signature,
32
@@ -1346,6 +1216,7 @@ static const struct signature_alg ecdsa_with_sha1_alg = {
&_hx509_signature_sha1_data,
PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
0,
+ NULL,
ecdsa_verify_signature,
ecdsa_create_signature,
20
@@ -1361,6 +1232,7 @@ static const struct signature_alg heim_rsa_pkcs1_x509 = {
NULL,
PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
0,
+ NULL,
rsa_verify_signature,
rsa_create_signature
};
@@ -1373,6 +1245,7 @@ static const struct signature_alg pkcs1_rsa_sha1_alg = {
NULL,
PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
0,
+ NULL,
rsa_verify_signature,
rsa_create_signature
};
@@ -1385,6 +1258,7 @@ static const struct signature_alg rsa_with_sha256_alg = {
&_hx509_signature_sha256_data,
PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
0,
+ NULL,
rsa_verify_signature,
rsa_create_signature
};
@@ -1397,6 +1271,7 @@ static const struct signature_alg rsa_with_sha1_alg = {
&_hx509_signature_sha1_data,
PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
0,
+ NULL,
rsa_verify_signature,
rsa_create_signature
};
@@ -1409,6 +1284,7 @@ static const struct signature_alg rsa_with_md5_alg = {
&_hx509_signature_md5_data,
PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
1230739889,
+ NULL,
rsa_verify_signature,
rsa_create_signature
};
@@ -1421,6 +1297,7 @@ static const struct signature_alg rsa_with_md2_alg = {
&_hx509_signature_md2_data,
PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
1230739889,
+ NULL,
rsa_verify_signature,
rsa_create_signature
};
@@ -1433,6 +1310,7 @@ static const struct signature_alg dsa_sha1_alg = {
&_hx509_signature_sha1_data,
PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
0,
+ NULL,
dsa_verify_signature,
/* create_signature */ NULL,
};
@@ -1445,8 +1323,9 @@ static const struct signature_alg sha256_alg = {
NULL,
SIG_DIGEST,
0,
- sha256_verify_signature,
- sha256_create_signature
+ EVP_sha256,
+ evp_md_verify_signature,
+ evp_md_create_signature
};
static const struct signature_alg sha1_alg = {
@@ -1457,8 +1336,9 @@ static const struct signature_alg sha1_alg = {
NULL,
SIG_DIGEST,
0,
- sha1_verify_signature,
- sha1_create_signature
+ EVP_sha1,
+ evp_md_verify_signature,
+ evp_md_create_signature
};
static const struct signature_alg md5_alg = {
@@ -1469,7 +1349,9 @@ static const struct signature_alg md5_alg = {
NULL,
SIG_DIGEST,
0,
- md5_verify_signature
+ EVP_md5,
+ evp_md_verify_signature,
+ NULL
};
static const struct signature_alg md2_alg = {
@@ -1480,7 +1362,9 @@ static const struct signature_alg md2_alg = {
NULL,
SIG_DIGEST,
0,
- md2_verify_signature
+ EVP_md2,
+ evp_md_verify_signature,
+ NULL
};
/*
@@ -1599,12 +1483,16 @@ _hx509_signature_best_before(hx509_context context,
int
_hx509_verify_signature(hx509_context context,
- const Certificate *signer,
+ const hx509_cert cert,
const AlgorithmIdentifier *alg,
const heim_octet_string *data,
const heim_octet_string *sig)
{
const struct signature_alg *md;
+ const Certificate *signer = NULL;
+
+ if (cert)
+ signer = _hx509_get_cert(cert);
md = find_sig_alg(&alg->algorithm);
if (md == NULL) {
@@ -1632,27 +1520,6 @@ _hx509_verify_signature(hx509_context context,
}
int
-_hx509_verify_signature_bitstring(hx509_context context,
- const Certificate *signer,
- const AlgorithmIdentifier *alg,
- const heim_octet_string *data,
- const heim_bit_string *sig)
-{
- heim_octet_string os;
-
- if (sig->length & 7) {
- hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
- "signature not multiple of 8 bits");
- return HX509_CRYPTO_SIG_INVALID_FORMAT;
- }
-
- os.data = sig->data;
- os.length = sig->length / 8;
-
- return _hx509_verify_signature(context, signer, alg, data, &os);
-}
-
-int
_hx509_create_signature(hx509_context context,
const hx509_private_key signer,
const AlgorithmIdentifier *alg,
@@ -1711,39 +1578,23 @@ _hx509_public_encrypt(hx509_context context,
int tosize;
int ret;
RSA *rsa;
- RSAPublicKey pk;
size_t size;
+ const unsigned char *p;
ciphertext->data = NULL;
ciphertext->length = 0;
spi = &cert->tbsCertificate.subjectPublicKeyInfo;
- rsa = RSA_new();
+ p = spi->subjectPublicKey.data;
+ size = spi->subjectPublicKey.length / 8;
+
+ rsa = d2i_RSAPublicKey(NULL, &p, size);
if (rsa == NULL) {
hx509_set_error_string(context, 0, ENOMEM, "out of memory");
return ENOMEM;
}
- ret = decode_RSAPublicKey(spi->subjectPublicKey.data,
- spi->subjectPublicKey.length / 8,
- &pk, &size);
- if (ret) {
- RSA_free(rsa);
- hx509_set_error_string(context, 0, ret, "RSAPublicKey decode failure");
- return ret;
- }
- rsa->n = heim_int2BN(&pk.modulus);
- rsa->e = heim_int2BN(&pk.publicExponent);
-
- free_RSAPublicKey(&pk);
-
- if (rsa->n == NULL || rsa->e == NULL) {
- RSA_free(rsa);
- hx509_set_error_string(context, 0, ENOMEM, "out of memory");
- return ENOMEM;
- }
-
tosize = RSA_size(rsa);
to = malloc(tosize);
if (to == NULL) {
diff --git a/source4/heimdal/lib/hx509/ks_dir.c b/source4/heimdal/lib/hx509/ks_dir.c
index a627fc65a2..9ce9b5c8e6 100644
--- a/source4/heimdal/lib/hx509/ks_dir.c
+++ b/source4/heimdal/lib/hx509/ks_dir.c
@@ -93,8 +93,6 @@ dir_free(hx509_certs certs, void *data)
return 0;
}
-
-
static int
dir_iter_start(hx509_context context,
hx509_certs certs, void *data, void **cursor)
diff --git a/source4/heimdal/lib/hx509/name.c b/source4/heimdal/lib/hx509/name.c
index 546b749015..c5844f98cc 100644
--- a/source4/heimdal/lib/hx509/name.c
+++ b/source4/heimdal/lib/hx509/name.c
@@ -399,7 +399,7 @@ _hx509_name_ds_cmp(const DirectoryString *ds1,
int *diff)
{
uint32_t *ds1lp, *ds2lp;
- size_t ds1len, ds2len;
+ size_t ds1len, ds2len, i;
int ret;
ret = dsstringprep(ds1, &ds1lp, &ds1len);
@@ -413,9 +413,13 @@ _hx509_name_ds_cmp(const DirectoryString *ds1,
if (ds1len != ds2len)
*diff = ds1len - ds2len;
- else
- *diff = memcmp(ds1lp, ds2lp, ds1len * sizeof(ds1lp[0]));
-
+ else {
+ for (i = 0; i < ds1len; i++) {
+ *diff = ds1lp[i] - ds2lp[i];
+ if (*diff)
+ break;
+ }
+ }
free(ds1lp);
free(ds2lp);
diff --git a/source4/heimdal/lib/hx509/print.c b/source4/heimdal/lib/hx509/print.c
index ddafb7f46e..56e4f72115 100644
--- a/source4/heimdal/lib/hx509/print.c
+++ b/source4/heimdal/lib/hx509/print.c
@@ -1017,7 +1017,7 @@ hx509_validate_cert(hx509_context context,
if (status.selfsigned) {
ret = _hx509_verify_signature_bitstring(context,
- c,
+ cert,
&c->signatureAlgorithm,
&c->tbsCertificate._save,
&c->signatureValue);
diff --git a/source4/heimdal/lib/hx509/revoke.c b/source4/heimdal/lib/hx509/revoke.c
index adb31164c1..74f2d74679 100644
--- a/source4/heimdal/lib/hx509/revoke.c
+++ b/source4/heimdal/lib/hx509/revoke.c
@@ -223,7 +223,7 @@ verify_ocsp(hx509_context context,
}
ret = _hx509_verify_signature_bitstring(context,
- p,
+ parent,
&s->signatureAlgorithm,
&s->tbsCertificate._save,
&s->signatureValue);
@@ -240,7 +240,7 @@ verify_ocsp(hx509_context context,
}
ret = _hx509_verify_signature_bitstring(context,
- _hx509_get_cert(signer),
+ signer,
&ocsp->ocsp.signatureAlgorithm,
&ocsp->ocsp.tbsResponseData._save,
&ocsp->ocsp.signature);
@@ -506,7 +506,7 @@ verify_crl(hx509_context context,
}
ret = _hx509_verify_signature_bitstring(context,
- _hx509_get_cert(signer),
+ signer,
&crl->signatureAlgorithm,
&crl->tbsCertList._save,
&crl->signatureValue);
diff --git a/source4/heimdal/lib/krb5/cache.c b/source4/heimdal/lib/krb5/cache.c
index 12097470d5..3617a0eefd 100644
--- a/source4/heimdal/lib/krb5/cache.c
+++ b/source4/heimdal/lib/krb5/cache.c
@@ -119,8 +119,8 @@ krb5_cc_register(krb5_context context,
{
int i;
- for(i = 0; i < context->num_cc_ops && context->cc_ops[i].prefix; i++) {
- if(strcmp(context->cc_ops[i].prefix, ops->prefix) == 0) {
+ for(i = 0; i < context->num_cc_ops && context->cc_ops[i]->prefix; i++) {
+ if(strcmp(context->cc_ops[i]->prefix, ops->prefix) == 0) {
if(!override) {
krb5_set_error_message(context,
KRB5_CC_TYPE_EXISTS,
@@ -132,20 +132,19 @@ krb5_cc_register(krb5_context context,
}
}
if(i == context->num_cc_ops) {
- krb5_cc_ops *o = realloc(context->cc_ops,
- (context->num_cc_ops + 1) *
- sizeof(*context->cc_ops));
+ const krb5_cc_ops **o = realloc(context->cc_ops,
+ (context->num_cc_ops + 1) *
+ sizeof(context->cc_ops[0]));
if(o == NULL) {
krb5_set_error_message(context, KRB5_CC_NOMEM,
N_("malloc: out of memory", ""));
return KRB5_CC_NOMEM;
}
- context->num_cc_ops++;
context->cc_ops = o;
- memset(context->cc_ops + i, 0,
- (context->num_cc_ops - i) * sizeof(*context->cc_ops));
+ context->cc_ops[context->num_cc_ops] = NULL;
+ context->num_cc_ops++;
}
- memcpy(&context->cc_ops[i], ops, sizeof(context->cc_ops[i]));
+ context->cc_ops[i] = ops;
return 0;
}
@@ -219,12 +218,12 @@ krb5_cc_resolve(krb5_context context,
*id = NULL;
- for(i = 0; i < context->num_cc_ops && context->cc_ops[i].prefix; i++) {
- size_t prefix_len = strlen(context->cc_ops[i].prefix);
+ for(i = 0; i < context->num_cc_ops && context->cc_ops[i]->prefix; i++) {
+ size_t prefix_len = strlen(context->cc_ops[i]->prefix);
- if(strncmp(context->cc_ops[i].prefix, name, prefix_len) == 0
+ if(strncmp(context->cc_ops[i]->prefix, name, prefix_len) == 0
&& name[prefix_len] == ':') {
- return allocate_ccache (context, &context->cc_ops[i],
+ return allocate_ccache (context, context->cc_ops[i],
name + prefix_len + 1,
id);
}
@@ -673,6 +672,13 @@ krb5_cc_store_cred(krb5_context context,
* from `id' in `creds'. 'creds' must be free by the caller using
* krb5_free_cred_contents.
*
+ * @param context A Kerberos 5 context
+ * @param id a Kerberos 5 credential cache
+ * @param whichfields what fields to use for matching credentials, same
+ * flags as whichfields in krb5_compare_creds()
+ * @param mcreds template credential to use for comparing
+ * @param creds returned credential, free with krb5_free_cred_contents()
+ *
* @return Return an error code or 0, see krb5_get_error_message().
*
* @ingroup krb5_ccache
@@ -970,10 +976,10 @@ krb5_cc_get_prefix_ops(krb5_context context, const char *prefix)
if (p1)
*p1 = '\0';
- for(i = 0; i < context->num_cc_ops && context->cc_ops[i].prefix; i++) {
- if(strcmp(context->cc_ops[i].prefix, p) == 0) {
+ for(i = 0; i < context->num_cc_ops && context->cc_ops[i]->prefix; i++) {
+ if(strcmp(context->cc_ops[i]->prefix, p) == 0) {
free(p);
- return &context->cc_ops[i];
+ return context->cc_ops[i];
}
}
free(p);
@@ -1046,6 +1052,10 @@ krb5_cc_cache_get_first (krb5_context context,
* Retrieve the next cache pointed to by (`cursor') in `id'
* and advance `cursor'.
*
+ * @param context A Kerberos 5 context
+ * @param cursor the iterator cursor, returned by krb5_cc_cache_get_first()
+ * @param id next ccache
+ *
* @return Return 0 or an error code. Returns KRB5_CC_END when the end
* of caches is reached, see krb5_get_error_message().
*
@@ -1398,7 +1408,7 @@ krb5_cccol_cursor_next(krb5_context context, krb5_cccol_cursor cursor,
if (cursor->cursor == NULL) {
ret = krb5_cc_cache_get_first (context,
- context->cc_ops[cursor->idx].prefix,
+ context->cc_ops[cursor->idx]->prefix,
&cursor->cursor);
if (ret) {
cursor->idx++;
diff --git a/source4/heimdal/lib/krb5/config_file.c b/source4/heimdal/lib/krb5/config_file.c
index ee226c78a2..03c0e335d4 100644
--- a/source4/heimdal/lib/krb5/config_file.c
+++ b/source4/heimdal/lib/krb5/config_file.c
@@ -31,6 +31,8 @@
* SUCH DAMAGE.
*/
+#define KRB5_DEPRECATED
+
#include "krb5_locl.h"
/* Gaah! I want a portable funopen */
@@ -278,27 +280,6 @@ krb5_config_parse_debug (struct fileptr *f,
return 0;
}
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_config_parse_string_multi(krb5_context context,
- const char *string,
- krb5_config_section **res)
-{
- const char *str;
- unsigned lineno = 0;
- krb5_error_code ret;
- struct fileptr f;
- f.f = NULL;
- f.s = string;
-
- ret = krb5_config_parse_debug (&f, res, &lineno, &str);
- if (ret) {
- krb5_set_error_message (context, ret, "%s:%u: %s",
- "<constant>", lineno, str);
- return ret;
- }
- return 0;
-}
-
/**
* Parse a configuration file and add the result into res. This
* interface can be used to parse several configuration files into one
@@ -403,6 +384,19 @@ free_binding (krb5_context context, krb5_config_binding *b)
}
}
+/**
+ * Free configuration file section, the result of
+ * krb5_config_parse_file() and krb5_config_parse_file_multi().
+ *
+ * @param context A Kerberos 5 context
+ * @param s the configuration section to free
+ *
+ * @return returns 0 on successes, otherwise an error code, see
+ * krb5_get_error_message()
+ *
+ * @ingroup krb5_support
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_config_file_free (krb5_context context, krb5_config_section *s)
{
@@ -410,6 +404,8 @@ krb5_config_file_free (krb5_context context, krb5_config_section *s)
return 0;
}
+#ifndef HEIMDAL_SMALLER
+
krb5_error_code
_krb5_config_copy(krb5_context context,
krb5_config_section *c,
@@ -444,20 +440,20 @@ _krb5_config_copy(krb5_context context,
return 0;
}
-
+#endif /* HEIMDAL_SMALLER */
const void *
-krb5_config_get_next (krb5_context context,
- const krb5_config_section *c,
- const krb5_config_binding **pointer,
- int type,
- ...)
+_krb5_config_get_next (krb5_context context,
+ const krb5_config_section *c,
+ const krb5_config_binding **pointer,
+ int type,
+ ...)
{
const char *ret;
va_list args;
va_start(args, type);
- ret = krb5_config_vget_next (context, c, pointer, type, args);
+ ret = _krb5_config_vget_next (context, c, pointer, type, args);
va_end(args);
return ret;
}
@@ -486,11 +482,11 @@ vget_next(krb5_context context,
}
const void *
-krb5_config_vget_next (krb5_context context,
- const krb5_config_section *c,
- const krb5_config_binding **pointer,
- int type,
- va_list args)
+_krb5_config_vget_next (krb5_context context,
+ const krb5_config_section *c,
+ const krb5_config_binding **pointer,
+ int type,
+ va_list args)
{
const krb5_config_binding *b;
const char *p;
@@ -522,31 +518,43 @@ krb5_config_vget_next (krb5_context context,
}
const void *
-krb5_config_get (krb5_context context,
- const krb5_config_section *c,
- int type,
- ...)
+_krb5_config_get (krb5_context context,
+ const krb5_config_section *c,
+ int type,
+ ...)
{
const void *ret;
va_list args;
va_start(args, type);
- ret = krb5_config_vget (context, c, type, args);
+ ret = _krb5_config_vget (context, c, type, args);
va_end(args);
return ret;
}
const void *
-krb5_config_vget (krb5_context context,
- const krb5_config_section *c,
- int type,
- va_list args)
+_krb5_config_vget (krb5_context context,
+ const krb5_config_section *c,
+ int type,
+ va_list args)
{
const krb5_config_binding *foo = NULL;
- return krb5_config_vget_next (context, c, &foo, type, args);
+ return _krb5_config_vget_next (context, c, &foo, type, args);
}
+/**
+ * Get a list of configuration binding list for more processing
+ *
+ * @param context A Kerberos 5 context.
+ * @param c a configuration section, or NULL to use the section from context
+ * @param ... a list of names, terminated with NULL.
+ *
+ * @return NULL if configuration list is not found, a list otherwise
+ *
+ * @ingroup krb5_support
+ */
+
const krb5_config_binding *
krb5_config_get_list (krb5_context context,
const krb5_config_section *c,
@@ -561,14 +569,41 @@ krb5_config_get_list (krb5_context context,
return ret;
}
+/**
+ * Get a list of configuration binding list for more processing
+ *
+ * @param context A Kerberos 5 context.
+ * @param c a configuration section, or NULL to use the section from context
+ * @param args a va_list of arguments
+ *
+ * @return NULL if configuration list is not found, a list otherwise
+ *
+ * @ingroup krb5_support
+ */
+
const krb5_config_binding *
krb5_config_vget_list (krb5_context context,
const krb5_config_section *c,
va_list args)
{
- return krb5_config_vget (context, c, krb5_config_list, args);
+ return _krb5_config_vget (context, c, krb5_config_list, args);
}
+/**
+ * Returns a "const char *" to a string in the configuration database.
+ * The string may not be valid after a reload of the configuration
+ * database so a caller should make a local copy if it needs to keep
+ * the string.
+ *
+ * @param context A Kerberos 5 context.
+ * @param c a configuration section, or NULL to use the section from context
+ * @param ... a list of names, terminated with NULL.
+ *
+ * @return NULL if configuration string not found, a string otherwise
+ *
+ * @ingroup krb5_support
+ */
+
const char* KRB5_LIB_FUNCTION
krb5_config_get_string (krb5_context context,
const krb5_config_section *c,
@@ -583,14 +618,41 @@ krb5_config_get_string (krb5_context context,
return ret;
}
+/**
+ * Like krb5_config_get_string(), but uses a va_list instead of ...
+ *
+ * @param context A Kerberos 5 context.
+ * @param c a configuration section, or NULL to use the section from context
+ * @param args a va_list of arguments
+ *
+ * @return NULL if configuration string not found, a string otherwise
+ *
+ * @ingroup krb5_support
+ */
+
const char* KRB5_LIB_FUNCTION
krb5_config_vget_string (krb5_context context,
const krb5_config_section *c,
va_list args)
{
- return krb5_config_vget (context, c, krb5_config_string, args);
+ return _krb5_config_vget (context, c, krb5_config_string, args);
}
+/**
+ * Like krb5_config_vget_string(), but instead of returning NULL,
+ * instead return a default value.
+ *
+ * @param context A Kerberos 5 context.
+ * @param c a configuration section, or NULL to use the section from context
+ * @param def_value the default value to return if no configuration
+ * found in the database.
+ * @param args a va_list of arguments
+ *
+ * @return a configuration string
+ *
+ * @ingroup krb5_support
+ */
+
const char* KRB5_LIB_FUNCTION
krb5_config_vget_string_default (krb5_context context,
const krb5_config_section *c,
@@ -605,6 +667,21 @@ krb5_config_vget_string_default (krb5_context context,
return ret;
}
+/**
+ * Like krb5_config_get_string(), but instead of returning NULL,
+ * instead return a default value.
+ *
+ * @param context A Kerberos 5 context.
+ * @param c a configuration section, or NULL to use the section from context
+ * @param def_value the default value to return if no configuration
+ * found in the database.
+ * @param ... a list of names, terminated with NULL.
+ *
+ * @return a configuration string
+ *
+ * @ingroup krb5_support
+ */
+
const char* KRB5_LIB_FUNCTION
krb5_config_get_string_default (krb5_context context,
const krb5_config_section *c,
@@ -620,6 +697,19 @@ krb5_config_get_string_default (krb5_context context,
return ret;
}
+/**
+ * Get a list of configuration strings, free the result with
+ * krb5_config_free_strings().
+ *
+ * @param context A Kerberos 5 context.
+ * @param c a configuration section, or NULL to use the section from context
+ * @param args a va_list of arguments
+ *
+ * @return TRUE or FALSE
+ *
+ * @ingroup krb5_support
+ */
+
char ** KRB5_LIB_FUNCTION
krb5_config_vget_strings(krb5_context context,
const krb5_config_section *c,
@@ -630,8 +720,8 @@ krb5_config_vget_strings(krb5_context context,
const krb5_config_binding *b = NULL;
const char *p;
- while((p = krb5_config_vget_next(context, c, &b,
- krb5_config_string, args))) {
+ while((p = _krb5_config_vget_next(context, c, &b,
+ krb5_config_string, args))) {
char *tmp = strdup(p);
char *pos = NULL;
char *s;
@@ -667,6 +757,19 @@ cleanup:
}
+/**
+ * Get a list of configuration strings, free the result with
+ * krb5_config_free_strings().
+ *
+ * @param context A Kerberos 5 context.
+ * @param c a configuration section, or NULL to use the section from context
+ * @param ... a list of names, terminated with NULL.
+ *
+ * @return TRUE or FALSE
+ *
+ * @ingroup krb5_support
+ */
+
char**
krb5_config_get_strings(krb5_context context,
const krb5_config_section *c,
@@ -680,6 +783,15 @@ krb5_config_get_strings(krb5_context context,
return ret;
}
+/**
+ * Free the resulting strings from krb5_config-get_strings() and
+ * krb5_config_vget_strings().
+ *
+ * @param strings strings to free
+ *
+ * @ingroup krb5_support
+ */
+
void KRB5_LIB_FUNCTION
krb5_config_free_strings(char **strings)
{
@@ -691,6 +803,24 @@ krb5_config_free_strings(char **strings)
free(strings);
}
+/**
+ * Like krb5_config_get_bool_default() but with a va_list list of
+ * configuration selection.
+ *
+ * Configuration value to a boolean value, where yes/true and any
+ * non-zero number means TRUE and other value is FALSE.
+ *
+ * @param context A Kerberos 5 context.
+ * @param c a configuration section, or NULL to use the section from context
+ * @param def_value the default value to return if no configuration
+ * found in the database.
+ * @param args a va_list of arguments
+ *
+ * @return TRUE or FALSE
+ *
+ * @ingroup krb5_support
+ */
+
krb5_boolean KRB5_LIB_FUNCTION
krb5_config_vget_bool_default (krb5_context context,
const krb5_config_section *c,
@@ -707,6 +837,20 @@ krb5_config_vget_bool_default (krb5_context context,
return FALSE;
}
+/**
+ * krb5_config_get_bool() will convert the configuration
+ * option value to a boolean value, where yes/true and any non-zero
+ * number means TRUE and other value is FALSE.
+ *
+ * @param context A Kerberos 5 context.
+ * @param c a configuration section, or NULL to use the section from context
+ * @param args a va_list of arguments
+ *
+ * @return TRUE or FALSE
+ *
+ * @ingroup krb5_support
+ */
+
krb5_boolean KRB5_LIB_FUNCTION
krb5_config_vget_bool (krb5_context context,
const krb5_config_section *c,
@@ -715,6 +859,22 @@ krb5_config_vget_bool (krb5_context context,
return krb5_config_vget_bool_default (context, c, FALSE, args);
}
+/**
+ * krb5_config_get_bool_default() will convert the configuration
+ * option value to a boolean value, where yes/true and any non-zero
+ * number means TRUE and other value is FALSE.
+ *
+ * @param context A Kerberos 5 context.
+ * @param c a configuration section, or NULL to use the section from context
+ * @param def_value the default value to return if no configuration
+ * found in the database.
+ * @param ... a list of names, terminated with NULL.
+ *
+ * @return TRUE or FALSE
+ *
+ * @ingroup krb5_support
+ */
+
krb5_boolean KRB5_LIB_FUNCTION
krb5_config_get_bool_default (krb5_context context,
const krb5_config_section *c,
@@ -729,6 +889,22 @@ krb5_config_get_bool_default (krb5_context context,
return ret;
}
+/**
+ * Like krb5_config_get_bool() but with a va_list list of
+ * configuration selection.
+ *
+ * Configuration value to a boolean value, where yes/true and any
+ * non-zero number means TRUE and other value is FALSE.
+ *
+ * @param context A Kerberos 5 context.
+ * @param c a configuration section, or NULL to use the section from context
+ * @param ... a list of names, terminated with NULL.
+ *
+ * @return TRUE or FALSE
+ *
+ * @ingroup krb5_support
+ */
+
krb5_boolean KRB5_LIB_FUNCTION
krb5_config_get_bool (krb5_context context,
const krb5_config_section *c,
@@ -742,6 +918,23 @@ krb5_config_get_bool (krb5_context context,
return ret;
}
+/**
+ * Get the time from the configuration file using a relative time.
+ *
+ * Like krb5_config_get_time_default() but with a va_list list of
+ * configuration selection.
+ *
+ * @param context A Kerberos 5 context.
+ * @param c a configuration section, or NULL to use the section from context
+ * @param def_value the default value to return if no configuration
+ * found in the database.
+ * @param args a va_list of arguments
+ *
+ * @return parsed the time (or def_value on parse error)
+ *
+ * @ingroup krb5_support
+ */
+
int KRB5_LIB_FUNCTION
krb5_config_vget_time_default (krb5_context context,
const krb5_config_section *c,
@@ -759,14 +952,40 @@ krb5_config_vget_time_default (krb5_context context,
return t;
}
+/**
+ * Get the time from the configuration file using a relative time, for example: 1h30s
+ *
+ * @param context A Kerberos 5 context.
+ * @param c a configuration section, or NULL to use the section from context
+ * @param args a va_list of arguments
+ *
+ * @return parsed the time or -1 on error
+ *
+ * @ingroup krb5_support
+ */
+
int KRB5_LIB_FUNCTION
-krb5_config_vget_time (krb5_context context,
- const krb5_config_section *c,
- va_list args)
+krb5_config_vget_time(krb5_context context,
+ const krb5_config_section *c,
+ va_list args)
{
return krb5_config_vget_time_default (context, c, -1, args);
}
+/**
+ * Get the time from the configuration file using a relative time, for example: 1h30s
+ *
+ * @param context A Kerberos 5 context.
+ * @param c a configuration section, or NULL to use the section from context
+ * @param def_value the default value to return if no configuration
+ * found in the database.
+ * @param ... a list of names, terminated with NULL.
+ *
+ * @return parsed the time (or def_value on parse error)
+ *
+ * @ingroup krb5_support
+ */
+
int KRB5_LIB_FUNCTION
krb5_config_get_time_default (krb5_context context,
const krb5_config_section *c,
@@ -781,6 +1000,18 @@ krb5_config_get_time_default (krb5_context context,
return ret;
}
+/**
+ * Get the time from the configuration file using a relative time, for example: 1h30s
+ *
+ * @param context A Kerberos 5 context.
+ * @param c a configuration section, or NULL to use the section from context
+ * @param ... a list of names, terminated with NULL.
+ *
+ * @return parsed the time or -1 on error
+ *
+ * @ingroup krb5_support
+ */
+
int KRB5_LIB_FUNCTION
krb5_config_get_time (krb5_context context,
const krb5_config_section *c,
@@ -850,3 +1081,29 @@ krb5_config_get_int (krb5_context context,
va_end(ap);
return ret;
}
+
+
+#ifndef HEIMDAL_SMALLER
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_config_parse_string_multi(krb5_context context,
+ const char *string,
+ krb5_config_section **res) KRB5_DEPRECATED
+{
+ const char *str;
+ unsigned lineno = 0;
+ krb5_error_code ret;
+ struct fileptr f;
+ f.f = NULL;
+ f.s = string;
+
+ ret = krb5_config_parse_debug (&f, res, &lineno, &str);
+ if (ret) {
+ krb5_set_error_message (context, ret, "%s:%u: %s",
+ "<constant>", lineno, str);
+ return ret;
+ }
+ return 0;
+}
+
+#endif
diff --git a/source4/heimdal/lib/krb5/context.c b/source4/heimdal/lib/krb5/context.c
index 9ece38e145..8bf8b79022 100644
--- a/source4/heimdal/lib/krb5/context.c
+++ b/source4/heimdal/lib/krb5/context.c
@@ -85,32 +85,6 @@ set_etypes (krb5_context context,
}
/*
- *
- */
-
-static krb5_error_code
-copy_etypes (krb5_context context,
- krb5_enctype *enctypes,
- krb5_enctype **ret_enctypes)
-{
- unsigned int i;
-
- for (i = 0; enctypes[i]; i++)
- ;
- i++;
-
- *ret_enctypes = malloc(sizeof(ret_enctypes[0]) * i);
- if (*ret_enctypes == NULL) {
- krb5_set_error_message(context, ENOMEM,
- N_("malloc: out of memory", ""));
- return ENOMEM;
- }
- memcpy(*ret_enctypes, enctypes, sizeof(ret_enctypes[0]) * i);
- return 0;
-}
-
-
-/*
* read variables from the configuration file and set in `context'
*/
@@ -119,6 +93,7 @@ init_context_from_config_file(krb5_context context)
{
krb5_error_code ret;
const char * tmp;
+ char **s;
krb5_enctype *tmptypes;
INIT_FIELD(context, time, max_skew, 5 * 60, "clockskew");
@@ -229,6 +204,16 @@ init_context_from_config_file(krb5_context context)
krb5_enctype_enable(context, ETYPE_DES_PCBC_NONE);
}
+ s = krb5_config_get_strings(context, NULL, "logging", "krb5", NULL);
+ if(s) {
+ char **p;
+ krb5_initlog(context, "libkrb5", &context->debug_dest);
+ for(p = s; *p; p++)
+ krb5_addlog_dest(context, context->debug_dest, *p);
+ krb5_config_free_strings(s);
+ }
+
+
return 0;
}
@@ -328,8 +313,35 @@ out:
return ret;
}
+#ifndef HEIMDAL_SMALLER
+
+/*
+ *
+ */
+
+static krb5_error_code
+copy_etypes (krb5_context context,
+ krb5_enctype *enctypes,
+ krb5_enctype **ret_enctypes)
+{
+ unsigned int i;
+
+ for (i = 0; enctypes[i]; i++)
+ ;
+ i++;
+
+ *ret_enctypes = malloc(sizeof(ret_enctypes[0]) * i);
+ if (*ret_enctypes == NULL) {
+ krb5_set_error_message(context, ENOMEM,
+ N_("malloc: out of memory", ""));
+ return ENOMEM;
+ }
+ memcpy(*ret_enctypes, enctypes, sizeof(ret_enctypes[0]) * i);
+ return 0;
+}
+
/**
- * Make a copy for the Kerberos 5 context, allocated krb5_contex shoud
+ * Make a copy for the Kerberos 5 context, the new krb5_context shoud
* be freed with krb5_free_context().
*
* @param context the Kerberos context to copy
@@ -399,6 +411,8 @@ krb5_copy_context(krb5_context context, krb5_context *out)
#if 0 /* XXX */
if(context->warn_dest != NULL)
;
+ if(context->debug_dest != NULL)
+ ;
#endif
ret = krb5_set_extra_addresses(p, context->extra_addresses);
@@ -421,6 +435,8 @@ krb5_copy_context(krb5_context context, krb5_context *out)
return ret;
}
+#endif
+
/**
* Frees the krb5_context allocated by krb5_init_context().
*
@@ -446,6 +462,8 @@ krb5_free_context(krb5_context context)
krb5_clear_error_message(context);
if(context->warn_dest != NULL)
krb5_closelog(context, context->warn_dest);
+ if(context->debug_dest != NULL)
+ krb5_closelog(context, context->debug_dest);
krb5_set_extra_addresses(context, NULL);
krb5_set_ignore_addresses(context, NULL);
krb5_set_send_to_kdc_func(context, NULL, NULL);
@@ -835,21 +853,24 @@ krb5_init_ets(krb5_context context)
{
if(context->et_list == NULL){
krb5_add_et_list(context, initialize_krb5_error_table_r);
- bindtextdomain(COM_ERR_BINDDOMAIN_krb5, HEIMDAL_LOCALEDIR);
-
krb5_add_et_list(context, initialize_asn1_error_table_r);
- bindtextdomain(COM_ERR_BINDDOMAIN_asn1, HEIMDAL_LOCALEDIR);
-
krb5_add_et_list(context, initialize_heim_error_table_r);
- bindtextdomain(COM_ERR_BINDDOMAIN_heim, HEIMDAL_LOCALEDIR);
krb5_add_et_list(context, initialize_k524_error_table_r);
+
+#ifdef COM_ERR_BINDDOMAIN_krb5
+ bindtextdomain(COM_ERR_BINDDOMAIN_krb5, HEIMDAL_LOCALEDIR);
+ bindtextdomain(COM_ERR_BINDDOMAIN_asn1, HEIMDAL_LOCALEDIR);
+ bindtextdomain(COM_ERR_BINDDOMAIN_heim, HEIMDAL_LOCALEDIR);
bindtextdomain(COM_ERR_BINDDOMAIN_k524, HEIMDAL_LOCALEDIR);
+#endif
#ifdef PKINIT
krb5_add_et_list(context, initialize_hx_error_table_r);
+#ifdef COM_ERR_BINDDOMAIN_hx
bindtextdomain(COM_ERR_BINDDOMAIN_hx, HEIMDAL_LOCALEDIR);
#endif
+#endif
}
}
diff --git a/source4/heimdal/lib/krb5/creds.c b/source4/heimdal/lib/krb5/creds.c
index 26c0dfbecb..6cc2714172 100644
--- a/source4/heimdal/lib/krb5/creds.c
+++ b/source4/heimdal/lib/krb5/creds.c
@@ -183,6 +183,18 @@ krb5_times_equal(const krb5_times *a, const krb5_times *b)
* Return TRUE if `mcreds' and `creds' are equal (`whichfields'
* determines what equal means).
*
+ *
+ * The following flags, set in whichfields affects the comparison:
+ * - KRB5_TC_MATCH_SRV_NAMEONLY Consider all realms equal when comparing the service principal.
+ * - KRB5_TC_MATCH_KEYTYPE Compare enctypes.
+ * - KRB5_TC_MATCH_FLAGS_EXACT Make sure that the ticket flags are identical.
+ * - KRB5_TC_MATCH_FLAGS Make sure that all ticket flags set in mcreds are also present in creds .
+ * - KRB5_TC_MATCH_TIMES_EXACT Compares the ticket times exactly.
+ * - KRB5_TC_MATCH_TIMES Compares only the expiration times of the creds.
+ * - KRB5_TC_MATCH_AUTHDATA Compares the authdata fields.
+ * - KRB5_TC_MATCH_2ND_TKT Compares the second tickets (used by user-to-user authentication).
+ * - KRB5_TC_MATCH_IS_SKEY Compares the existance of the second ticket.
+ *
* @param context Kerberos 5 context.
* @param whichfields which fields to compare.
* @param mcreds cred to compare with.
diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c
index 42e2fdf359..bdcdb2ea0a 100644
--- a/source4/heimdal/lib/krb5/crypto.c
+++ b/source4/heimdal/lib/krb5/crypto.c
@@ -36,20 +36,10 @@
#include "krb5_locl.h"
#include <pkinit_asn1.h>
-#define WEAK_ENCTYPES 1
-
#ifndef HEIMDAL_SMALLER
#define DES3_OLD_ENCTYPE 1
#endif
-
-#ifdef HAVE_OPENSSL /* XXX forward decl for hcrypto glue */
-const EVP_CIPHER * _krb5_EVP_hcrypto_aes_128_cts(void);
-const EVP_CIPHER * _krb5_EVP_hcrypto_aes_256_cts(void);
-#define EVP_hcrypto_aes_128_cts _krb5_EVP_hcrypto_aes_128_cts
-#define EVP_hcrypto_aes_256_cts _krb5_EVP_hcrypto_aes_256_cts
-#endif
-
struct key_data {
krb5_keyblock *key;
krb5_data *schedule;
@@ -180,7 +170,7 @@ struct evp_schedule {
static HEIMDAL_MUTEX crypto_mutex = HEIMDAL_MUTEX_INITIALIZER;
-#ifdef WEAK_ENCTYPES
+#ifdef HEIM_WEAK_CRYPTO
static void
krb5_DES_random_key(krb5_context context,
krb5_keyblock *key)
@@ -555,15 +545,6 @@ DES3_random_to_key(krb5_context context,
* ARCFOUR
*/
-static void
-ARCFOUR_schedule(krb5_context context,
- struct key_type *kt,
- struct key_data *kd)
-{
- RC4_set_key (kd->schedule->data,
- kd->key->keyvalue.length, kd->key->keyvalue.data);
-}
-
static krb5_error_code
ARCFOUR_string_to_key(krb5_context context,
krb5_enctype enctype,
@@ -722,7 +703,7 @@ evp_cleanup(krb5_context context, struct key_data *kd)
*
*/
-#ifdef WEAK_ENCTYPES
+#ifdef HEIM_WEAK_CRYPTO
static struct salt_type des_salt[] = {
{
KRB5_PW_SALT,
@@ -793,7 +774,7 @@ static struct key_type keytype_null = {
NULL
};
-#ifdef WEAK_ENCTYPES
+#ifdef HEIM_WEAK_CRYPTO
static struct key_type keytype_des_old = {
KEYTYPE_DES,
"des-old",
@@ -819,7 +800,7 @@ static struct key_type keytype_des = {
evp_cleanup,
EVP_des_cbc
};
-#endif /* WEAK_ENCTYPES */
+#endif /* HEIM_WEAK_CRYPTO */
#ifdef DES3_OLD_ENCTYPE
static struct key_type keytype_des3 = {
@@ -862,7 +843,7 @@ static struct key_type keytype_aes128 = {
AES_salt,
NULL,
evp_cleanup,
- EVP_hcrypto_aes_128_cts
+ EVP_aes_128_cbc
};
static struct key_type keytype_aes256 = {
@@ -876,7 +857,7 @@ static struct key_type keytype_aes256 = {
AES_salt,
NULL,
evp_cleanup,
- EVP_hcrypto_aes_256_cts
+ EVP_aes_256_cbc
};
static struct key_type keytype_arcfour = {
@@ -884,10 +865,13 @@ static struct key_type keytype_arcfour = {
"arcfour",
128,
16,
- sizeof(RC4_KEY),
+ sizeof(struct evp_schedule),
+ NULL,
+ evp_schedule,
+ arcfour_salt,
NULL,
- ARCFOUR_schedule,
- arcfour_salt
+ evp_cleanup,
+ EVP_rc4
};
krb5_error_code KRB5_LIB_FUNCTION
@@ -1204,37 +1188,7 @@ NONE_checksum(krb5_context context,
return 0;
}
-static krb5_error_code
-CRC32_checksum(krb5_context context,
- struct key_data *key,
- const void *data,
- size_t len,
- unsigned usage,
- Checksum *C)
-{
- uint32_t crc;
- unsigned char *r = C->checksum.data;
- _krb5_crc_init_table ();
- crc = _krb5_crc_update (data, len, 0);
- r[0] = crc & 0xff;
- r[1] = (crc >> 8) & 0xff;
- r[2] = (crc >> 16) & 0xff;
- r[3] = (crc >> 24) & 0xff;
- return 0;
-}
-
-static krb5_error_code
-RSA_MD4_checksum(krb5_context context,
- struct key_data *key,
- const void *data,
- size_t len,
- unsigned usage,
- Checksum *C)
-{
- if (EVP_Digest(data, len, C->checksum.data, NULL, EVP_md4(), NULL) != 1)
- krb5_abortx(context, "md4 checksum failed");
- return 0;
-}
+#if defined(DES3_OLD_ENCTYPE) || defined(HEIM_WEAK_CRYPTO)
static krb5_error_code
des_checksum(krb5_context context,
@@ -1299,7 +1253,7 @@ des_verify(krb5_context context,
EVP_DigestUpdate(m, data, len);
EVP_DigestFinal_ex (m, res, NULL);
EVP_MD_CTX_destroy(m);
- if(memcmp(res, tmp + 8, sizeof(res)) != 0) {
+ if(ct_memcmp(res, tmp + 8, sizeof(res)) != 0) {
krb5_clear_error_message (context);
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
}
@@ -1308,6 +1262,42 @@ des_verify(krb5_context context,
return ret;
}
+#endif
+
+#ifdef HEIM_WEAK_CRYPTO
+
+static krb5_error_code
+CRC32_checksum(krb5_context context,
+ struct key_data *key,
+ const void *data,
+ size_t len,
+ unsigned usage,
+ Checksum *C)
+{
+ uint32_t crc;
+ unsigned char *r = C->checksum.data;
+ _krb5_crc_init_table ();
+ crc = _krb5_crc_update (data, len, 0);
+ r[0] = crc & 0xff;
+ r[1] = (crc >> 8) & 0xff;
+ r[2] = (crc >> 16) & 0xff;
+ r[3] = (crc >> 24) & 0xff;
+ return 0;
+}
+
+static krb5_error_code
+RSA_MD4_checksum(krb5_context context,
+ struct key_data *key,
+ const void *data,
+ size_t len,
+ unsigned usage,
+ Checksum *C)
+{
+ if (EVP_Digest(data, len, C->checksum.data, NULL, EVP_md4(), NULL) != 1)
+ krb5_abortx(context, "md4 checksum failed");
+ return 0;
+}
+
static krb5_error_code
RSA_MD4_DES_checksum(krb5_context context,
struct key_data *key,
@@ -1331,19 +1321,6 @@ RSA_MD4_DES_verify(krb5_context context,
}
static krb5_error_code
-RSA_MD5_checksum(krb5_context context,
- struct key_data *key,
- const void *data,
- size_t len,
- unsigned usage,
- Checksum *C)
-{
- if (EVP_Digest(data, len, C->checksum.data, NULL, EVP_md5(), NULL) != 1)
- krb5_abortx(context, "md5 checksum failed");
- return 0;
-}
-
-static krb5_error_code
RSA_MD5_DES_checksum(krb5_context context,
struct key_data *key,
const void *data,
@@ -1365,6 +1342,8 @@ RSA_MD5_DES_verify(krb5_context context,
return des_verify(context, EVP_md5(), key, data, len, C);
}
+#endif /* HEIM_WEAK_CRYPTO */
+
#ifdef DES3_OLD_ENCTYPE
static krb5_error_code
RSA_MD5_DES3_checksum(krb5_context context,
@@ -1576,6 +1555,7 @@ static struct checksum_type checksum_none = {
NONE_checksum,
NULL
};
+#ifdef HEIM_WEAK_CRYPTO
static struct checksum_type checksum_crc32 = {
CKSUMTYPE_CRC32,
"crc32",
@@ -1603,15 +1583,6 @@ static struct checksum_type checksum_rsa_md4_des = {
RSA_MD4_DES_checksum,
RSA_MD4_DES_verify
};
-static struct checksum_type checksum_rsa_md5 = {
- CKSUMTYPE_RSA_MD5,
- "rsa-md5",
- 64,
- 16,
- F_CPROOF,
- RSA_MD5_checksum,
- NULL
-};
static struct checksum_type checksum_rsa_md5_des = {
CKSUMTYPE_RSA_MD5_DES,
"rsa-md5-des",
@@ -1621,6 +1592,31 @@ static struct checksum_type checksum_rsa_md5_des = {
RSA_MD5_DES_checksum,
RSA_MD5_DES_verify
};
+#endif /* HEIM_WEAK_CRYPTO */
+
+static krb5_error_code
+RSA_MD5_checksum(krb5_context context,
+ struct key_data *key,
+ const void *data,
+ size_t len,
+ unsigned usage,
+ Checksum *C)
+{
+ if (EVP_Digest(data, len, C->checksum.data, NULL, EVP_md5(), NULL) != 1)
+ krb5_abortx(context, "md5 checksum failed");
+ return 0;
+}
+
+static struct checksum_type checksum_rsa_md5 = {
+ CKSUMTYPE_RSA_MD5,
+ "rsa-md5",
+ 64,
+ 16,
+ F_CPROOF,
+ RSA_MD5_checksum,
+ NULL
+};
+
#ifdef DES3_OLD_ENCTYPE
static struct checksum_type checksum_rsa_md5_des3 = {
CKSUMTYPE_RSA_MD5_DES3,
@@ -1683,14 +1679,16 @@ static struct checksum_type checksum_hmac_md5 = {
static struct checksum_type *checksum_types[] = {
&checksum_none,
+#ifdef HEIM_WEAK_CRYPTO
&checksum_crc32,
&checksum_rsa_md4,
&checksum_rsa_md4_des,
- &checksum_rsa_md5,
&checksum_rsa_md5_des,
+#endif
#ifdef DES3_OLD_ENCTYPE
&checksum_rsa_md5_des3,
#endif
+ &checksum_rsa_md5,
&checksum_sha1,
&checksum_hmac_sha1_des3,
&checksum_hmac_sha1_aes128,
@@ -1889,7 +1887,7 @@ verify_checksum(krb5_context context,
}
if(c.checksum.length != cksum->checksum.length ||
- memcmp(c.checksum.data, cksum->checksum.data, c.checksum.length)) {
+ ct_memcmp(c.checksum.data, cksum->checksum.data, c.checksum.length)) {
krb5_clear_error_message (context);
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
} else {
@@ -2060,7 +2058,103 @@ evp_encrypt(krb5_context context,
return 0;
}
-#ifdef WEAK_ENCTYPES
+static const char zero_ivec[EVP_MAX_BLOCK_LENGTH] = { 0 };
+
+static krb5_error_code
+evp_encrypt_cts(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ krb5_boolean encryptp,
+ int usage,
+ void *ivec)
+{
+ size_t i, blocksize;
+ struct evp_schedule *ctx = key->schedule->data;
+ char tmp[EVP_MAX_BLOCK_LENGTH], ivec2[EVP_MAX_BLOCK_LENGTH];
+ EVP_CIPHER_CTX *c;
+ unsigned char *p;
+
+ c = encryptp ? &ctx->ectx : &ctx->dctx;
+
+ blocksize = EVP_CIPHER_CTX_block_size(c);
+
+ if (len < blocksize) {
+ krb5_set_error_message(context, EINVAL,
+ "message block too short");
+ return EINVAL;
+ } else if (len == blocksize) {
+ EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1);
+ EVP_Cipher(c, data, data, len);
+ return 0;
+ }
+
+ if (ivec)
+ EVP_CipherInit_ex(c, NULL, NULL, NULL, ivec, -1);
+ else
+ EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1);
+
+ if (encryptp) {
+
+ p = data;
+ i = ((len - 1) / blocksize) * blocksize;
+ EVP_Cipher(c, p, p, i);
+ p += i - blocksize;
+ len -= i;
+ memcpy(ivec2, p, blocksize);
+
+ for (i = 0; i < len; i++)
+ tmp[i] = p[i + blocksize] ^ ivec2[i];
+ for (; i < blocksize; i++)
+ tmp[i] = 0 ^ ivec2[i];
+
+ EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1);
+ EVP_Cipher(c, p, tmp, blocksize);
+
+ memcpy(p + blocksize, ivec2, len);
+ if (ivec)
+ memcpy(ivec, p, blocksize);
+ } else {
+ char tmp2[EVP_MAX_BLOCK_LENGTH], tmp3[EVP_MAX_BLOCK_LENGTH];
+
+ p = data;
+ if (len > blocksize * 2) {
+ /* remove last two blocks and round up, decrypt this with cbc, then do cts dance */
+ i = ((((len - blocksize * 2) + blocksize - 1) / blocksize) * blocksize);
+ memcpy(ivec2, p + i - blocksize, blocksize);
+ EVP_Cipher(c, p, p, i);
+ p += i;
+ len -= i + blocksize;
+ } else {
+ if (ivec)
+ memcpy(ivec2, ivec, blocksize);
+ else
+ memcpy(ivec2, zero_ivec, blocksize);
+ len -= blocksize;
+ }
+
+ memcpy(tmp, p, blocksize);
+ EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1);
+ EVP_Cipher(c, tmp2, p, blocksize);
+
+ memcpy(tmp3, p + blocksize, len);
+ memcpy(tmp3 + len, tmp2 + len, blocksize - len); /* xor 0 */
+
+ for (i = 0; i < len; i++)
+ p[i + blocksize] = tmp2[i] ^ tmp3[i];
+
+ EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1);
+ EVP_Cipher(c, p, tmp3, blocksize);
+
+ for (i = 0; i < blocksize; i++)
+ p[i] ^= ivec2[i];
+ if (ivec)
+ memcpy(ivec, tmp, blocksize);
+ }
+ return 0;
+}
+
+#ifdef HEIM_WEAK_CRYPTO
static krb5_error_code
evp_des_encrypt_null_ivec(krb5_context context,
struct key_data *key,
@@ -2149,12 +2243,12 @@ ARCFOUR_subencrypt(krb5_context context,
unsigned usage,
void *ivec)
{
+ EVP_CIPHER_CTX ctx;
struct checksum_type *c = _find_checksum (CKSUMTYPE_RSA_MD5);
Checksum k1_c, k2_c, k3_c, cksum;
struct key_data ke;
krb5_keyblock kb;
unsigned char t[4];
- RC4_KEY rc4_key;
unsigned char *cdata = data;
unsigned char k1_c_data[16], k2_c_data[16], k3_c_data[16];
krb5_error_code ret;
@@ -2196,8 +2290,12 @@ ARCFOUR_subencrypt(krb5_context context,
if (ret)
krb5_abortx(context, "hmac failed");
- RC4_set_key (&rc4_key, k3_c.checksum.length, k3_c.checksum.data);
- RC4 (&rc4_key, len - 16, cdata + 16, cdata + 16);
+ EVP_CIPHER_CTX_init(&ctx);
+
+ EVP_CipherInit_ex(&ctx, EVP_rc4(), NULL, k3_c.checksum.data, NULL, 1);
+ EVP_Cipher(&ctx, cdata + 16, cdata + 16, len - 16);
+ EVP_CIPHER_CTX_cleanup(&ctx);
+
memset (k1_c_data, 0, sizeof(k1_c_data));
memset (k2_c_data, 0, sizeof(k2_c_data));
memset (k3_c_data, 0, sizeof(k3_c_data));
@@ -2212,12 +2310,12 @@ ARCFOUR_subdecrypt(krb5_context context,
unsigned usage,
void *ivec)
{
+ EVP_CIPHER_CTX ctx;
struct checksum_type *c = _find_checksum (CKSUMTYPE_RSA_MD5);
Checksum k1_c, k2_c, k3_c, cksum;
struct key_data ke;
krb5_keyblock kb;
unsigned char t[4];
- RC4_KEY rc4_key;
unsigned char *cdata = data;
unsigned char k1_c_data[16], k2_c_data[16], k3_c_data[16];
unsigned char cksum_data[16];
@@ -2250,8 +2348,10 @@ ARCFOUR_subdecrypt(krb5_context context,
if (ret)
krb5_abortx(context, "hmac failed");
- RC4_set_key (&rc4_key, k3_c.checksum.length, k3_c.checksum.data);
- RC4 (&rc4_key, len - 16, cdata + 16, cdata + 16);
+ EVP_CIPHER_CTX_init(&ctx);
+ EVP_CipherInit_ex(&ctx, EVP_rc4(), NULL, k3_c.checksum.data, NULL, 0);
+ EVP_Cipher(&ctx, cdata + 16, cdata + 16, len - 16);
+ EVP_CIPHER_CTX_cleanup(&ctx);
ke.key = &kb;
kb.keyvalue = k2_c.checksum;
@@ -2267,7 +2367,7 @@ ARCFOUR_subdecrypt(krb5_context context,
memset (k2_c_data, 0, sizeof(k2_c_data));
memset (k3_c_data, 0, sizeof(k3_c_data));
- if (memcmp (cksum.checksum.data, data, 16) != 0) {
+ if (ct_memcmp (cksum.checksum.data, data, 16) != 0) {
krb5_clear_error_message (context);
return KRB5KRB_AP_ERR_BAD_INTEGRITY;
} else {
@@ -2471,7 +2571,7 @@ static struct encryption_type enctype_aes128_cts_hmac_sha1 = {
&checksum_sha1,
&checksum_hmac_sha1_aes128,
F_DERIVED,
- evp_encrypt,
+ evp_encrypt_cts,
16,
AES_PRF
};
@@ -2485,7 +2585,7 @@ static struct encryption_type enctype_aes256_cts_hmac_sha1 = {
&checksum_sha1,
&checksum_hmac_sha1_aes256,
F_DERIVED,
- evp_encrypt,
+ evp_encrypt_cts,
16,
AES_PRF
};
@@ -2503,7 +2603,7 @@ static struct encryption_type enctype_des3_cbc_none = {
0,
NULL
};
-#ifdef WEAK_ENCTYPES
+#ifdef HEIM_WEAK_CRYPTO
static struct encryption_type enctype_des_cbc_crc = {
ETYPE_DES_CBC_CRC,
"des-cbc-crc",
@@ -2588,7 +2688,7 @@ static struct encryption_type enctype_des_pcbc_none = {
0,
NULL
};
-#endif /* WEAK_ENCTYPES */
+#endif /* HEIM_WEAK_CRYPTO */
static struct encryption_type *etypes[] = {
&enctype_aes256_cts_hmac_sha1,
@@ -2600,7 +2700,7 @@ static struct encryption_type *etypes[] = {
&enctype_des3_cbc_md5,
&enctype_old_des3_cbc_sha1,
#endif
-#ifdef WEAK_ENCTYPES
+#ifdef HEIM_WEAK_CRYPTO
&enctype_des_cbc_crc,
&enctype_des_cbc_md4,
&enctype_des_cbc_md5,
@@ -3584,6 +3684,7 @@ krb5_create_checksum_iov(krb5_context context,
* @param usage Key usage for this buffer
* @param data array of buffers to process
* @param num_data length of array
+ * @param type return checksum type if not NULL
*
* @return Return an error code or 0.
* @ingroup krb5_crypto
@@ -4044,6 +4145,23 @@ _get_derived_key(krb5_context context,
return 0;
}
+/**
+ * Create a crypto context used for all encryption and signature
+ * operation. The encryption type to use is taken from the key, but
+ * can be overridden with the enctype parameter. This can be useful
+ * for encryptions types which is compatiable (DES for example).
+ *
+ * To free the crypto context, use krb5_crypto_destroy().
+ *
+ * @param context Kerberos context
+ * @param key the key block information with all key data
+ * @param etype the encryption type
+ * @param crypto the resulting crypto context
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_crypto
+ */
krb5_error_code KRB5_LIB_FUNCTION
krb5_crypto_init(krb5_context context,
@@ -4116,6 +4234,17 @@ free_key_usage(krb5_context context, struct key_usage *ku,
free_key_data(context, &ku->key, et);
}
+/**
+ * Free a crypto context created by krb5_crypto_init().
+ *
+ * @param context Kerberos context
+ * @param crypto crypto context to free
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_crypto
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_crypto_destroy(krb5_context context,
krb5_crypto crypto)
@@ -4130,6 +4259,18 @@ krb5_crypto_destroy(krb5_context context,
return 0;
}
+/**
+ * Return the blocksize used algorithm referenced by the crypto context
+ *
+ * @param context Kerberos context
+ * @param crypto crypto context to query
+ * @param blocksize the resulting blocksize
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_crypto
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_crypto_getblocksize(krb5_context context,
krb5_crypto crypto,
@@ -4139,6 +4280,18 @@ krb5_crypto_getblocksize(krb5_context context,
return 0;
}
+/**
+ * Return the encryption type used by the crypto context
+ *
+ * @param context Kerberos context
+ * @param crypto crypto context to query
+ * @param enctype the resulting encryption type
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_crypto
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_crypto_getenctype(krb5_context context,
krb5_crypto crypto,
@@ -4148,6 +4301,18 @@ krb5_crypto_getenctype(krb5_context context,
return 0;
}
+/**
+ * Return the padding size used by the crypto context
+ *
+ * @param context Kerberos context
+ * @param crypto crypto context to query
+ * @param padsize the return padding size
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_crypto
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_crypto_getpadsize(krb5_context context,
krb5_crypto crypto,
@@ -4157,6 +4322,18 @@ krb5_crypto_getpadsize(krb5_context context,
return 0;
}
+/**
+ * Return the confounder size used by the crypto context
+ *
+ * @param context Kerberos context
+ * @param crypto crypto context to query
+ * @param confoundersize the returned confounder size
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_crypto
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_crypto_getconfoundersize(krb5_context context,
krb5_crypto crypto,
@@ -4386,8 +4563,8 @@ krb5_crypto_overhead (krb5_context context, krb5_crypto crypto)
* @param context Kerberos 5 context
* @param type the enctype resulting key will be of
* @param data input random data to convert to a key
- * @param data size of input random data, at least krb5_enctype_keysize() long
- * @param data key, output key, free with krb5_free_keyblock_contents()
+ * @param size size of input random data, at least krb5_enctype_keysize() long
+ * @param key key, output key, free with krb5_free_keyblock_contents()
*
* @return Return an error code or 0.
*
@@ -4444,6 +4621,7 @@ _krb5_pk_octetstring2key(krb5_context context,
void *keydata;
unsigned char counter;
unsigned char shaoutput[SHA_DIGEST_LENGTH];
+ EVP_MD_CTX *m;
if(et == NULL) {
krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
@@ -4459,19 +4637,27 @@ _krb5_pk_octetstring2key(krb5_context context,
return ENOMEM;
}
+ m = EVP_MD_CTX_create();
+ if (m == NULL) {
+ free(keydata);
+ krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
+ return ENOMEM;
+ }
+
counter = 0;
offset = 0;
do {
- SHA_CTX m;
- SHA1_Init(&m);
- SHA1_Update(&m, &counter, 1);
- SHA1_Update(&m, dhdata, dhsize);
+ EVP_DigestInit_ex(m, EVP_sha1(), NULL);
+ EVP_DigestUpdate(m, &counter, 1);
+ EVP_DigestUpdate(m, dhdata, dhsize);
+
if (c_n)
- SHA1_Update(&m, c_n->data, c_n->length);
+ EVP_DigestUpdate(m, c_n->data, c_n->length);
if (k_n)
- SHA1_Update(&m, k_n->data, k_n->length);
- SHA1_Final(shaoutput, &m);
+ EVP_DigestUpdate(m, k_n->data, k_n->length);
+
+ EVP_DigestFinal_ex(m, shaoutput, NULL);
memcpy((unsigned char *)keydata + offset,
shaoutput,
@@ -4482,6 +4668,8 @@ _krb5_pk_octetstring2key(krb5_context context,
} while(offset < keylen);
memset(shaoutput, 0, sizeof(shaoutput));
+ EVP_MD_CTX_destroy(m);
+
ret = krb5_random_to_key(context, type, keydata, keylen, key);
memset(keydata, 0, sizeof(keylen));
free(keydata);
@@ -4595,6 +4783,7 @@ _krb5_pk_kdf(krb5_context context,
uint32_t counter;
unsigned char *keydata;
unsigned char shaoutput[SHA_DIGEST_LENGTH];
+ EVP_MD_CTX *m;
if (der_heim_oid_cmp(&asn1_oid_id_pkinit_kdf_ah_sha1, &ai->algorithm) != 0) {
krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
@@ -4633,18 +4822,26 @@ _krb5_pk_kdf(krb5_context context,
return ret;
}
+ m = EVP_MD_CTX_create();
+ if (m == NULL) {
+ free(keydata);
+ free(other.data);
+ krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
+ return ENOMEM;
+ }
+
offset = 0;
counter = 1;
do {
unsigned char cdata[4];
- SHA_CTX m;
- SHA1_Init(&m);
+ EVP_DigestInit_ex(m, EVP_sha1(), NULL);
_krb5_put_int(cdata, counter, 4);
- SHA1_Update(&m, cdata, 4);
- SHA1_Update(&m, dhdata, dhsize);
- SHA1_Update(&m, other.data, other.length);
- SHA1_Final(shaoutput, &m);
+ EVP_DigestUpdate(m, cdata, 4);
+ EVP_DigestUpdate(m, dhdata, dhsize);
+ EVP_DigestUpdate(m, other.data, other.length);
+
+ EVP_DigestFinal_ex(m, shaoutput, NULL);
memcpy((unsigned char *)keydata + offset,
shaoutput,
@@ -4655,6 +4852,7 @@ _krb5_pk_kdf(krb5_context context,
} while(offset < keylen);
memset(shaoutput, 0, sizeof(shaoutput));
+ EVP_MD_CTX_destroy(m);
free(other.data);
ret = krb5_random_to_key(context, enctype, keydata, keylen, key);
@@ -4765,7 +4963,7 @@ krb5_crypto_prfplus(krb5_context context,
* @param crypto1 first key to combine
* @param crypto2 second key to combine
* @param pepper1 factor to combine with first key to garante uniqueness
- * @param pepper1 factor to combine with second key to garante uniqueness
+ * @param pepper2 factor to combine with second key to garante uniqueness
* @param enctype the encryption type of the resulting key
* @param res allocated key, free with krb5_free_keyblock_contents()
*
diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c
index ff89a90d55..5363d533e7 100644
--- a/source4/heimdal/lib/krb5/init_creds_pw.c
+++ b/source4/heimdal/lib/krb5/init_creds_pw.c
@@ -398,6 +398,9 @@ get_init_creds_common(krb5_context context,
}
}
if (options->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST) {
+ if (ctx->etypes)
+ free(ctx->etypes);
+
etypes = malloc((options->etype_list_length + 1)
* sizeof(krb5_enctype));
if (etypes == NULL) {
@@ -1417,10 +1420,17 @@ krb5_init_creds_set_keytab(krb5_context context,
krb5_keytab keytab)
{
krb5_keytab_key_proc_args *a;
+ krb5_keytab_entry entry;
+ krb5_kt_cursor cursor;
+ krb5_enctype *etypes = NULL;
+ krb5_error_code ret;
+ size_t netypes = 0;
+ int kvno = 0;
a = malloc(sizeof(*a));
if (a == NULL) {
- krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
+ krb5_set_error_message(context, ENOMEM,
+ N_("malloc: out of memory", ""));
return ENOMEM;
}
@@ -1431,6 +1441,58 @@ krb5_init_creds_set_keytab(krb5_context context,
ctx->keyseed = (void *)a;
ctx->keyproc = keytab_key_proc;
+ /*
+ * We need to the KDC what enctypes we support for this keytab,
+ * esp if the keytab is really a password based entry, then the
+ * KDC might have more enctypes in the database then what we have
+ * in the keytab.
+ */
+
+ ret = krb5_kt_start_seq_get(context, keytab, &cursor);
+ if(ret)
+ goto out;
+
+ while(krb5_kt_next_entry(context, keytab, &entry, &cursor) == 0){
+ void *ptr;
+
+ if (!krb5_principal_compare(context, entry.principal, ctx->cred.client))
+ goto next;
+
+ /* check if we ahve this kvno already */
+ if (entry.vno > kvno) {
+ /* remove old list of etype */
+ if (etypes)
+ free(etypes);
+ netypes = 0;
+ kvno = entry.vno;
+ } else if (entry.vno != kvno)
+ goto next;
+
+ /* check if enctype is supported */
+ if (krb5_enctype_valid(context, entry.keyblock.keytype) != 0)
+ goto next;
+
+ /* add enctype to supported list */
+ ptr = realloc(etypes, sizeof(etypes[0]) * (netypes + 2));
+ if (ptr == NULL)
+ goto next;
+
+ etypes = ptr;
+ etypes[netypes] = entry.keyblock.keytype;
+ etypes[netypes + 1] = ETYPE_NULL;
+ netypes++;
+ next:
+ krb5_kt_free_entry(context, &entry);
+ }
+ krb5_kt_end_seq_get(context, keytab, &cursor);
+
+ if (etypes) {
+ if (ctx->etypes)
+ free(ctx->etypes);
+ ctx->etypes = etypes;
+ }
+
+ out:
return 0;
}
diff --git a/source4/heimdal/lib/krb5/keyblock.c b/source4/heimdal/lib/krb5/keyblock.c
index 57ed7875fc..046caee6d6 100644
--- a/source4/heimdal/lib/krb5/keyblock.c
+++ b/source4/heimdal/lib/krb5/keyblock.c
@@ -97,7 +97,7 @@ krb5_free_keyblock(krb5_context context,
* @param inblock the key to copy
* @param to the output key.
*
- * @param 0 on success or a Kerberos 5 error code
+ * @return 0 on success or a Kerberos 5 error code
*
* @ingroup krb5_crypto
*/
@@ -118,7 +118,7 @@ krb5_copy_keyblock_contents (krb5_context context,
* @param inblock the key to copy
* @param to the output key.
*
- * @param 0 on success or a Kerberos 5 error code
+ * @return 0 on success or a Kerberos 5 error code
*
* @ingroup krb5_crypto
*/
@@ -165,6 +165,8 @@ krb5_keyblock_get_enctype(const krb5_keyblock *block)
* Fill in `key' with key data of type `enctype' from `data' of length
* `size'. Key should be freed using krb5_free_keyblock_contents().
*
+ * @return 0 on success or a Kerberos 5 error code
+ *
* @ingroup krb5_crypto
*/
diff --git a/source4/heimdal/lib/krb5/krb5_locl.h b/source4/heimdal/lib/krb5/krb5_locl.h
index b56219cced..71dc1327c6 100644
--- a/source4/heimdal/lib/krb5/krb5_locl.h
+++ b/source4/heimdal/lib/krb5/krb5_locl.h
@@ -234,7 +234,8 @@ typedef struct krb5_context_data {
krb5_config_section *cf;
struct et_list *et_list;
struct krb5_log_facility *warn_dest;
- krb5_cc_ops *cc_ops;
+ struct krb5_log_facility *debug_dest;
+ const krb5_cc_ops **cc_ops;
int num_cc_ops;
const char *http_proxy;
const char *time_fmt;
diff --git a/source4/heimdal/lib/krb5/krbhst.c b/source4/heimdal/lib/krb5/krbhst.c
index e9111abec9..4e4b4562e5 100644
--- a/source4/heimdal/lib/krb5/krbhst.c
+++ b/source4/heimdal/lib/krb5/krbhst.c
@@ -86,8 +86,11 @@ srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count,
snprintf(domain, sizeof(domain), "_%s._%s.%s.", service, proto, realm);
r = rk_dns_lookup(domain, dns_type);
- if(r == NULL)
+ if(r == NULL) {
+ _krb5_debug(context, 0,
+ "DNS lookup failed domain: %s", domain);
return KRB5_KDC_UNREACH;
+ }
for(num_srv = 0, rr = r->head; rr; rr = rr->next)
if(rr->type == rk_ns_t_srv)
@@ -176,6 +179,15 @@ krbhst_get_default_proto(struct krb5_krbhst_data *kd)
return KRB5_KRBHST_UDP;
}
+/*
+ *
+ */
+
+const char *
+_krb5_krbhst_get_realm(krb5_krbhst_handle handle)
+{
+ return handle->realm;
+}
/*
* parse `spec' into a krb5_krbhst_info, defaulting the port to `def_port'
@@ -186,7 +198,7 @@ static struct krb5_krbhst_info*
parse_hostspec(krb5_context context, struct krb5_krbhst_data *kd,
const char *spec, int def_port, int port)
{
- const char *p = spec;
+ const char *p = spec, *q;
struct krb5_krbhst_info *hi;
hi = calloc(1, sizeof(*hi) + strlen(spec));
@@ -209,7 +221,17 @@ parse_hostspec(krb5_context context, struct krb5_krbhst_data *kd,
p += 4;
}
- if(strsep_copy(&p, ":", hi->hostname, strlen(spec) + 1) < 0) {
+ if (p[0] == '[' && (q = strchr(p, ']')) != NULL) {
+ /* if address looks like [foo:bar] or [foo:bar]: its a ipv6
+ adress, strip of [] */
+ memcpy(hi->hostname, &p[1], q - p - 1);
+ hi->hostname[q - p - 1] = '\0';
+ p = q + 1;
+ /* get trailing : */
+ if (p[0] == ':')
+ p++;
+ } else if(strsep_copy(&p, ":", hi->hostname, strlen(spec) + 1) < 0) {
+ /* copy everything before : */
free(hi);
return NULL;
}
@@ -218,7 +240,7 @@ parse_hostspec(krb5_context context, struct krb5_krbhst_data *kd,
strlwr(hi->hostname);
hi->port = hi->def_port = def_port;
- if(p != NULL) {
+ if(p != NULL && p[0]) {
char *end;
hi->port = strtol(p, &end, 0);
if(end == p) {
@@ -374,11 +396,15 @@ static void
srv_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
const char *proto, const char *service)
{
+ krb5_error_code ret;
krb5_krbhst_info **res;
int count, i;
- if (srv_find_realm(context, &res, &count, kd->realm, "SRV", proto, service,
- kd->port))
+ ret = srv_find_realm(context, &res, &count, kd->realm, "SRV", proto, service,
+ kd->port);
+ _krb5_debug(context, 2, "searching DNS for realm %s %s.%s -> %d",
+ kd->realm, proto, service, ret);
+ if (ret)
return;
for(i = 0; i < count; i++)
append_host_hostinfo(kd, res[i]);
@@ -395,11 +421,13 @@ config_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
const char *conf_string)
{
int i;
-
char **hostlist;
hostlist = krb5_config_get_strings(context, NULL,
"realms", kd->realm, conf_string, NULL);
+ _krb5_debug(context, 2, "configuration file for realm %s%s found",
+ kd->realm, hostlist ? "" : " not");
+
if(hostlist == NULL)
return;
kd->flags |= KD_CONFIG_EXISTS;
@@ -426,6 +454,9 @@ fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
struct addrinfo hints;
char portstr[NI_MAXSERV];
+ _krb5_debug(context, 2, "fallback lookup %d for realm %s (service %s)",
+ kd->fallback_count, kd->realm, serv_string);
+
/*
* Don't try forever in case the DNS server keep returning us
* entries (like wildcard entries or the .nu TLD)
@@ -545,8 +576,10 @@ plugin_get_hosts(krb5_context context,
N_("Locate plugin failed to lookup realm %s: %d", ""),
kd->realm, ret);
break;
- } else if (ret == 0)
+ } else if (ret == 0) {
+ _krb5_debug(context, 2, "plugin found result for realm %s", kd->realm);
kd->flags |= KD_CONFIG_EXISTS;
+ }
}
_krb5_plugin_free(list);
@@ -577,8 +610,12 @@ kdc_get_next(krb5_context context,
return 0;
}
- if (kd->flags & KD_CONFIG_EXISTS)
- return KRB5_KDC_UNREACH; /* XXX */
+ if (kd->flags & KD_CONFIG_EXISTS) {
+ _krb5_debug(context, 1,
+ "Configuration exists for realm %s, wont go to DNS",
+ kd->realm);
+ return KRB5_KDC_UNREACH;
+ }
if(context->srv_lookup) {
if((kd->flags & KD_SRV_UDP) == 0 && (kd->flags & KD_LARGE_MSG) == 0) {
@@ -612,6 +649,8 @@ kdc_get_next(krb5_context context,
return 0;
}
+ _krb5_debug(context, 0, "No KDC entries found for %s", kd->realm);
+
return KRB5_KDC_UNREACH; /* XXX */
}
@@ -636,8 +675,12 @@ admin_get_next(krb5_context context,
return 0;
}
- if (kd->flags & KD_CONFIG_EXISTS)
- return KRB5_KDC_UNREACH; /* XXX */
+ if (kd->flags & KD_CONFIG_EXISTS) {
+ _krb5_debug(context, 1,
+ "Configuration exists for realm %s, wont go to DNS",
+ kd->realm);
+ return KRB5_KDC_UNREACH;
+ }
if(context->srv_lookup) {
if((kd->flags & KD_SRV_TCP) == 0) {
@@ -660,6 +703,8 @@ admin_get_next(krb5_context context,
return 0;
}
+ _krb5_debug(context, 0, "No admin entries found for realm %s", kd->realm);
+
return KRB5_KDC_UNREACH; /* XXX */
}
@@ -684,8 +729,12 @@ kpasswd_get_next(krb5_context context,
return 0;
}
- if (kd->flags & KD_CONFIG_EXISTS)
- return KRB5_KDC_UNREACH; /* XXX */
+ if (kd->flags & KD_CONFIG_EXISTS) {
+ _krb5_debug(context, 1,
+ "Configuration exists for realm %s, wont go to DNS",
+ kd->realm);
+ return KRB5_KDC_UNREACH;
+ }
if(context->srv_lookup) {
if((kd->flags & KD_SRV_UDP) == 0) {
@@ -714,7 +763,9 @@ kpasswd_get_next(krb5_context context,
return ret;
}
- return KRB5_KDC_UNREACH; /* XXX */
+ _krb5_debug(context, 0, "No kpasswd entries found for realm %s", kd->realm);
+
+ return KRB5_KDC_UNREACH;
}
static krb5_error_code
@@ -736,8 +787,12 @@ krb524_get_next(krb5_context context,
kd->flags |= KD_CONFIG;
}
- if (kd->flags & KD_CONFIG_EXISTS)
- return KRB5_KDC_UNREACH; /* XXX */
+ if (kd->flags & KD_CONFIG_EXISTS) {
+ _krb5_debug(context, 1,
+ "Configuration exists for realm %s, wont go to DNS",
+ kd->realm);
+ return KRB5_KDC_UNREACH;
+ }
if(context->srv_lookup) {
if((kd->flags & KD_SRV_UDP) == 0) {
@@ -764,11 +819,14 @@ krb524_get_next(krb5_context context,
return (*kd->get_next)(context, kd, host);
}
- return KRB5_KDC_UNREACH; /* XXX */
+ _krb5_debug(context, 0, "No kpasswd entries found for realm %s", kd->realm);
+
+ return KRB5_KDC_UNREACH;
}
static struct krb5_krbhst_data*
common_init(krb5_context context,
+ const char *service,
const char *realm,
int flags)
{
@@ -782,6 +840,9 @@ common_init(krb5_context context,
return NULL;
}
+ _krb5_debug(context, 2, "Trying to find service %s for realm %s flags %x",
+ service, realm, flags);
+
/* For 'realms' without a . do not even think of going to DNS */
if (!strchr(realm, '.'))
kd->flags |= KD_CONFIG_EXISTS;
@@ -816,32 +877,37 @@ krb5_krbhst_init_flags(krb5_context context,
krb5_error_code (*next)(krb5_context, struct krb5_krbhst_data *,
krb5_krbhst_info **);
int def_port;
+ const char *service;
switch(type) {
case KRB5_KRBHST_KDC:
next = kdc_get_next;
def_port = ntohs(krb5_getportbyname (context, "kerberos", "udp", 88));
+ service = "kdc";
break;
case KRB5_KRBHST_ADMIN:
next = admin_get_next;
def_port = ntohs(krb5_getportbyname (context, "kerberos-adm",
"tcp", 749));
+ service = "admin";
break;
case KRB5_KRBHST_CHANGEPW:
next = kpasswd_get_next;
def_port = ntohs(krb5_getportbyname (context, "kpasswd", "udp",
KPASSWD_PORT));
+ service = "change_password";
break;
case KRB5_KRBHST_KRB524:
next = krb524_get_next;
def_port = ntohs(krb5_getportbyname (context, "krb524", "udp", 4444));
+ service = "524";
break;
default:
krb5_set_error_message(context, ENOTTY,
N_("unknown krbhst type (%u)", ""), type);
return ENOTTY;
}
- if((kd = common_init(context, realm, flags)) == NULL)
+ if((kd = common_init(context, service, realm, flags)) == NULL)
return ENOMEM;
kd->get_next = next;
kd->def_port = def_port;
diff --git a/source4/heimdal/lib/krb5/log.c b/source4/heimdal/lib/krb5/log.c
index 5b84bc2f4c..9f81460973 100644
--- a/source4/heimdal/lib/krb5/log.c
+++ b/source4/heimdal/lib/krb5/log.c
@@ -488,3 +488,19 @@ krb5_log(krb5_context context,
return ret;
}
+void KRB5_LIB_FUNCTION
+_krb5_debug(krb5_context context,
+ int level,
+ const char *fmt,
+ ...)
+ __attribute__((format (printf, 3, 4)))
+{
+ va_list ap;
+
+ if (context == NULL || context->debug_dest == NULL)
+ return;
+
+ va_start(ap, fmt);
+ krb5_vlog(context, context->debug_dest, level, fmt, ap);
+ va_end(ap);
+}
diff --git a/source4/heimdal/lib/krb5/pkinit.c b/source4/heimdal/lib/krb5/pkinit.c
index af5568f44b..2f6d7854a5 100644
--- a/source4/heimdal/lib/krb5/pkinit.c
+++ b/source4/heimdal/lib/krb5/pkinit.c
@@ -1161,24 +1161,6 @@ pk_rd_pa_reply_enckey(krb5_context context,
}
der_free_oid(&contentType);
-#if 0 /* windows LH with interesting CMS packets, leaks memory */
- {
- size_t ph = 1 + der_length_len (length);
- unsigned char *ptr = malloc(length + ph);
- size_t l;
-
- memcpy(ptr + ph, p, length);
-
- ret = der_put_length_and_tag (ptr + ph - 1, ph, length,
- ASN1_C_UNIV, CONS, UT_Sequence, &l);
- if (ret)
- return ret;
- ptr += ph - l;
- length += l;
- p = ptr;
- }
-#endif
-
/* win2k uses ContentInfo */
if (type == PKINIT_WIN2K) {
heim_oid type;
@@ -1882,11 +1864,12 @@ pk_copy_error(krb5_context context,
{
va_list va;
char *s, *f;
+ int ret;
va_start(va, fmt);
- vasprintf(&f, fmt, va);
+ ret = vasprintf(&f, fmt, va);
va_end(va);
- if (f == NULL) {
+ if (ret == -1 || f == NULL) {
krb5_clear_error_message(context);
return;
}
@@ -2203,13 +2186,15 @@ _krb5_get_init_creds_opt_free_pkinit(krb5_get_init_creds_opt *opt)
ctx = opt->opt_private->pk_init_ctx;
switch (ctx->keyex) {
case USE_DH:
- DH_free(ctx->u.dh);
+ if (ctx->u.dh)
+ DH_free(ctx->u.dh);
break;
case USE_RSA:
break;
case USE_ECDH:
#ifdef HAVE_OPENSSL
- EC_KEY_free(ctx->u.eckey);
+ if (ctx->u.eckey)
+ EC_KEY_free(ctx->u.eckey);
#endif
break;
}
diff --git a/source4/heimdal/lib/krb5/principal.c b/source4/heimdal/lib/krb5/principal.c
index 9899f5661f..1483d59f9d 100644
--- a/source4/heimdal/lib/krb5/principal.c
+++ b/source4/heimdal/lib/krb5/principal.c
@@ -425,6 +425,19 @@ unparse_name_fixed(krb5_context context,
return 0;
}
+/**
+ * Unparse the principal name to a fixed buffer
+ *
+ * @param context A Kerberos context.
+ * @param principal principal to unparse
+ * @param name buffer to write name to
+ * @param len length of buffer
+ *
+ * @return An krb5 error code, see krb5_get_error_message().
+ *
+ * @ingroup krb5_principal
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_unparse_name_fixed(krb5_context context,
krb5_const_principal principal,
@@ -434,6 +447,20 @@ krb5_unparse_name_fixed(krb5_context context,
return unparse_name_fixed(context, principal, name, len, 0);
}
+/**
+ * Unparse the principal name to a fixed buffer. The realm is skipped
+ * if its a default realm.
+ *
+ * @param context A Kerberos context.
+ * @param principal principal to unparse
+ * @param name buffer to write name to
+ * @param len length of buffer
+ *
+ * @return An krb5 error code, see krb5_get_error_message().
+ *
+ * @ingroup krb5_principal
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_unparse_name_fixed_short(krb5_context context,
krb5_const_principal principal,
@@ -444,6 +471,20 @@ krb5_unparse_name_fixed_short(krb5_context context,
KRB5_PRINCIPAL_UNPARSE_SHORT);
}
+/**
+ * Unparse the principal name with unparse flags to a fixed buffer.
+ *
+ * @param context A Kerberos context.
+ * @param principal principal to unparse
+ * @param flags unparse flags
+ * @param name buffer to write name to
+ * @param len length of buffer
+ *
+ * @return An krb5 error code, see krb5_get_error_message().
+ *
+ * @ingroup krb5_principal
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_unparse_name_fixed_flags(krb5_context context,
krb5_const_principal principal,
@@ -538,6 +579,19 @@ krb5_unparse_name_flags(krb5_context context,
return unparse_name(context, principal, name, flags);
}
+/**
+ * Unparse the principal name to a allocated buffer. The realm is
+ * skipped if its a default realm.
+ *
+ * @param context A Kerberos context.
+ * @param principal principal to unparse
+ * @param name returned buffer, free with krb5_xfree()
+ *
+ * @return An krb5 error code, see krb5_get_error_message().
+ *
+ * @ingroup krb5_principal
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_unparse_name_short(krb5_context context,
krb5_const_principal principal,
@@ -546,18 +600,18 @@ krb5_unparse_name_short(krb5_context context,
return unparse_name(context, principal, name, KRB5_PRINCIPAL_UNPARSE_SHORT);
}
-#if 0 /* not implemented */
-
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_unparse_name_ext(krb5_context context,
- krb5_const_principal principal,
- char **name,
- size_t *size)
-{
- krb5_abortx(context, "unimplemented krb5_unparse_name_ext called");
-}
-
-#endif
+/**
+ * Set a new realm for a principal, and as a side-effect free the
+ * previous realm.
+ *
+ * @param context A Kerberos context.
+ * @param principal principal set the realm for
+ * @param realm the new realm to set
+ *
+ * @return An krb5 error code, see krb5_get_error_message().
+ *
+ * @ingroup krb5_principal
+ */
krb5_error_code KRB5_LIB_FUNCTION
krb5_principal_set_realm(krb5_context context,
diff --git a/source4/heimdal/lib/krb5/replay.c b/source4/heimdal/lib/krb5/replay.c
index 37556cfbc5..be484c29dc 100644
--- a/source4/heimdal/lib/krb5/replay.c
+++ b/source4/heimdal/lib/krb5/replay.c
@@ -178,17 +178,20 @@ krb5_rc_close(krb5_context context,
static void
checksum_authenticator(Authenticator *auth, void *data)
{
- MD5_CTX md5;
- int i;
+ EVP_MD_CTX *m = EVP_MD_CTX_create();
+ unsigned i;
- MD5_Init (&md5);
- MD5_Update (&md5, auth->crealm, strlen(auth->crealm));
+ EVP_DigestInit_ex(m, EVP_md5(), NULL);
+
+ EVP_DigestUpdate(m, auth->crealm, strlen(auth->crealm));
for(i = 0; i < auth->cname.name_string.len; i++)
- MD5_Update(&md5, auth->cname.name_string.val[i],
+ EVP_DigestUpdate(m, auth->cname.name_string.val[i],
strlen(auth->cname.name_string.val[i]));
- MD5_Update (&md5, &auth->ctime, sizeof(auth->ctime));
- MD5_Update (&md5, &auth->cusec, sizeof(auth->cusec));
- MD5_Final (data, &md5);
+ EVP_DigestUpdate(m, &auth->ctime, sizeof(auth->ctime));
+ EVP_DigestUpdate(m, &auth->cusec, sizeof(auth->cusec));
+
+ EVP_DigestFinal_ex(m, data, NULL);
+ EVP_MD_CTX_destroy(m);
}
krb5_error_code KRB5_LIB_FUNCTION
diff --git a/source4/heimdal/lib/krb5/send_to_kdc.c b/source4/heimdal/lib/krb5/send_to_kdc.c
index 50b42f2f10..0efe14eb4f 100644
--- a/source4/heimdal/lib/krb5/send_to_kdc.c
+++ b/source4/heimdal/lib/krb5/send_to_kdc.c
@@ -379,6 +379,10 @@ krb5_sendto (krb5_context context,
while (krb5_krbhst_next(context, handle, &hi) == 0) {
struct addrinfo *ai, *a;
+ _krb5_debug(context, 2,
+ "trying to communicate with host %s in realm %s",
+ hi->hostname, _krb5_krbhst_get_realm(handle));
+
if (context->send_to_kdc) {
struct send_to_kdc *s = context->send_to_kdc;
@@ -441,6 +445,9 @@ krb5_sendto (krb5_context context,
krb5_clear_error_message (context);
ret = KRB5_KDC_UNREACH;
out:
+ _krb5_debug(context, 2,
+ "result of trying to talk to realm %s = %d",
+ _krb5_krbhst_get_realm(handle), ret);
return ret;
}
diff --git a/source4/heimdal/lib/krb5/store.c b/source4/heimdal/lib/krb5/store.c
index 2ba83ef0d5..6e1374adf9 100644
--- a/source4/heimdal/lib/krb5/store.c
+++ b/source4/heimdal/lib/krb5/store.c
@@ -40,12 +40,30 @@
#define BYTEORDER_IS_HOST(SP) (BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_HOST) || \
krb5_storage_is_flags((SP), KRB5_STORAGE_HOST_BYTEORDER))
+/**
+ * Add the flags on a storage buffer by or-ing in the flags to the buffer.
+ *
+ * @param sp the storage buffer to set the flags on
+ * @param flags the flags to set
+ *
+ * @ingroup krb5_storage
+ */
+
void KRB5_LIB_FUNCTION
krb5_storage_set_flags(krb5_storage *sp, krb5_flags flags)
{
sp->flags |= flags;
}
+/**
+ * Clear the flags on a storage buffer
+ *
+ * @param sp the storage buffer to clear the flags on
+ * @param flags the flags to clear
+ *
+ * @ingroup krb5_storage
+ */
+
void KRB5_LIB_FUNCTION
krb5_storage_clear_flags(krb5_storage *sp, krb5_flags flags)
{
@@ -359,6 +377,18 @@ krb5_ret_int(krb5_storage *sp,
return 0;
}
+/**
+ * Read a int32 from storage, byte order is controlled by the settings
+ * on the storage, see krb5_storage_set_byteorder().
+ *
+ * @param sp the storage to write too
+ * @param value the value read from the buffer
+ *
+ * @return 0 for success, or a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_ret_int32(krb5_storage *sp,
int32_t *value)
@@ -373,6 +403,18 @@ krb5_ret_int32(krb5_storage *sp,
return 0;
}
+/**
+ * Read a uint32 from storage, byte order is controlled by the settings
+ * on the storage, see krb5_storage_set_byteorder().
+ *
+ * @param sp the storage to write too
+ * @param value the value read from the buffer
+ *
+ * @return 0 for success, or a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_ret_uint32(krb5_storage *sp,
uint32_t *value)
@@ -429,6 +471,17 @@ krb5_store_uint16(krb5_storage *sp,
return krb5_store_int16(sp, (int16_t)value);
}
+/**
+ * Read a int16 from storage, byte order is controlled by the settings
+ * on the storage, see krb5_storage_set_byteorder().
+ *
+ * @param sp the storage to write too
+ * @param value the value read from the buffer
+ *
+ * @return 0 for success, or a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
krb5_error_code KRB5_LIB_FUNCTION
krb5_ret_int16(krb5_storage *sp,
int16_t *value)
@@ -446,6 +499,18 @@ krb5_ret_int16(krb5_storage *sp,
return 0;
}
+/**
+ * Read a int16 from storage, byte order is controlled by the settings
+ * on the storage, see krb5_storage_set_byteorder().
+ *
+ * @param sp the storage to write too
+ * @param value the value read from the buffer
+ *
+ * @return 0 for success, or a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_ret_uint16(krb5_storage *sp,
uint16_t *value)
@@ -501,6 +566,17 @@ krb5_store_uint8(krb5_storage *sp,
return krb5_store_int8(sp, (int8_t)value);
}
+/**
+ * Read a int8 from storage
+ *
+ * @param sp the storage to write too
+ * @param value the value read from the buffer
+ *
+ * @return 0 for success, or a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_ret_int8(krb5_storage *sp,
int8_t *value)
@@ -513,6 +589,17 @@ krb5_ret_int8(krb5_storage *sp,
return 0;
}
+/**
+ * Read a uint8 from storage
+ *
+ * @param sp the storage to write too
+ * @param value the value read from the buffer
+ *
+ * @return 0 for success, or a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_ret_uint8(krb5_storage *sp,
uint8_t *value)
@@ -528,7 +615,8 @@ krb5_ret_uint8(krb5_storage *sp,
}
/**
- * Store a data to the storage.
+ * Store a data to the storage. The data is stored with an int32 as
+ * lenght plus the data (not padded).
*
* @param sp the storage buffer to write to
* @param data the buffer to store.
@@ -587,6 +675,18 @@ krb5_ret_data(krb5_storage *sp,
return 0;
}
+/**
+ * Store a string to the buffer. The data is formated as an len:uint32
+ * plus the string itself (not padded).
+ *
+ * @param sp the storage buffer to write to
+ * @param s the string to store.
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_store_string(krb5_storage *sp, const char *s)
{
@@ -596,6 +696,18 @@ krb5_store_string(krb5_storage *sp, const char *s)
return krb5_store_data(sp, data);
}
+/**
+ * Parse a string from the storage.
+ *
+ * @param sp the storage buffer to read from
+ * @param string the parsed string
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_ret_string(krb5_storage *sp,
char **string)
@@ -614,6 +726,18 @@ krb5_ret_string(krb5_storage *sp,
return 0;
}
+/**
+ * Store a zero terminated string to the buffer. The data is stored
+ * one character at a time until a NUL is stored.
+ *
+ * @param sp the storage buffer to write to
+ * @param s the string to store.
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_store_stringz(krb5_storage *sp, const char *s)
{
@@ -630,6 +754,17 @@ krb5_store_stringz(krb5_storage *sp, const char *s)
return 0;
}
+/**
+ * Parse zero terminated string from the storage.
+ *
+ * @param sp the storage buffer to read from
+ * @param string the parsed string
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_ret_stringz(krb5_storage *sp,
char **string)
@@ -733,6 +868,16 @@ krb5_ret_stringnl(krb5_storage *sp,
return 0;
}
+/**
+ * Write a principal block to storage.
+ *
+ * @param sp the storage buffer to write to
+ * @param p the principal block to write.
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
krb5_error_code KRB5_LIB_FUNCTION
krb5_store_principal(krb5_storage *sp,
@@ -760,6 +905,17 @@ krb5_store_principal(krb5_storage *sp,
return 0;
}
+/**
+ * Parse principal from the storage.
+ *
+ * @param sp the storage buffer to read from
+ * @param princ the parsed principal
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_ret_principal(krb5_storage *sp,
krb5_principal *princ)
@@ -931,6 +1087,17 @@ krb5_ret_times(krb5_storage *sp, krb5_times *times)
return ret;
}
+/**
+ * Write a address block to storage.
+ *
+ * @param sp the storage buffer to write to
+ * @param p the address block to write.
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_store_address(krb5_storage *sp, krb5_address p)
{
@@ -941,6 +1108,17 @@ krb5_store_address(krb5_storage *sp, krb5_address p)
return ret;
}
+/**
+ * Read a address block from the storage.
+ *
+ * @param sp the storage buffer to write to
+ * @param adr the address block read from storage
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_ret_address(krb5_storage *sp, krb5_address *adr)
{
@@ -953,6 +1131,17 @@ krb5_ret_address(krb5_storage *sp, krb5_address *adr)
return ret;
}
+/**
+ * Write a addresses block to storage.
+ *
+ * @param sp the storage buffer to write to
+ * @param p the addresses block to write.
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_store_addrs(krb5_storage *sp, krb5_addresses p)
{
@@ -967,6 +1156,17 @@ krb5_store_addrs(krb5_storage *sp, krb5_addresses p)
return ret;
}
+/**
+ * Read a addresses block from the storage.
+ *
+ * @param sp the storage buffer to write to
+ * @param adr the addresses block read from storage
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr)
{
@@ -987,6 +1187,17 @@ krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr)
return ret;
}
+/**
+ * Write a auth data block to storage.
+ *
+ * @param sp the storage buffer to write to
+ * @param auth the auth data block to write.
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_store_authdata(krb5_storage *sp, krb5_authdata auth)
{
@@ -1003,6 +1214,17 @@ krb5_store_authdata(krb5_storage *sp, krb5_authdata auth)
return 0;
}
+/**
+ * Read a auth data from the storage.
+ *
+ * @param sp the storage buffer to write to
+ * @param auth the auth data block read from storage
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth)
{
@@ -1037,9 +1259,15 @@ bitswap32(int32_t b)
return r;
}
-
-/*
+/**
+ * Write a credentials block to storage.
+ *
+ * @param sp the storage buffer to write to
+ * @param creds the creds block to write.
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
*
+ * @ingroup krb5_storage
*/
krb5_error_code KRB5_LIB_FUNCTION
@@ -1083,6 +1311,17 @@ krb5_store_creds(krb5_storage *sp, krb5_creds *creds)
return ret;
}
+/**
+ * Read a credentials block from the storage.
+ *
+ * @param sp the storage buffer to write to
+ * @param creds the credentials block read from storage
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_ret_creds(krb5_storage *sp, krb5_creds *creds)
{
@@ -1144,8 +1383,15 @@ cleanup:
#define SC_AUTHDATA 0x0020
#define SC_ADDRESSES 0x0040
-/*
+/**
+ * Write a tagged credentials block to storage.
+ *
+ * @param sp the storage buffer to write to
+ * @param creds the creds block to write.
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
*
+ * @ingroup krb5_storage
*/
krb5_error_code KRB5_LIB_FUNCTION
@@ -1229,6 +1475,17 @@ krb5_store_creds_tag(krb5_storage *sp, krb5_creds *creds)
return ret;
}
+/**
+ * Read a tagged credentials block from the storage.
+ *
+ * @param sp the storage buffer to write to
+ * @param creds the credentials block read from storage
+ *
+ * @return 0 on success, a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_ret_creds_tag(krb5_storage *sp,
krb5_creds *creds)
diff --git a/source4/heimdal/lib/krb5/store_mem.c b/source4/heimdal/lib/krb5/store_mem.c
index a7b0c2d2dc..a913e182d5 100644
--- a/source4/heimdal/lib/krb5/store_mem.c
+++ b/source4/heimdal/lib/krb5/store_mem.c
@@ -110,7 +110,7 @@ mem_no_trunc(krb5_storage *sp, off_t offset)
}
/**
- *
+ * Create a fixed size memory storage block
*
* @return A krb5_storage on success, or NULL on out of memory error.
*
@@ -149,7 +149,7 @@ krb5_storage_from_mem(void *buf, size_t len)
}
/**
- *
+ * Create a fixed size memory storage block
*
* @return A krb5_storage on success, or NULL on out of memory error.
*
@@ -168,7 +168,7 @@ krb5_storage_from_data(krb5_data *data)
}
/**
- *
+ * Create a fixed size memory storage block that is read only
*
* @return A krb5_storage on success, or NULL on out of memory error.
*
diff --git a/source4/heimdal/lib/krb5/ticket.c b/source4/heimdal/lib/krb5/ticket.c
index 86c4924506..3bd9387906 100644
--- a/source4/heimdal/lib/krb5/ticket.c
+++ b/source4/heimdal/lib/krb5/ticket.c
@@ -33,6 +33,18 @@
#include "krb5_locl.h"
+/**
+ * Free ticket and content
+ *
+ * @param context a Kerberos 5 context
+ * @param ticket ticket to free
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_free_ticket(krb5_context context,
krb5_ticket *ticket)
@@ -44,6 +56,19 @@ krb5_free_ticket(krb5_context context,
return 0;
}
+/**
+ * Copy ticket and content
+ *
+ * @param context a Kerberos 5 context
+ * @param from ticket to copy
+ * @param to new copy of ticket, free with krb5_free_ticket()
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_copy_ticket(krb5_context context,
const krb5_ticket *from,
@@ -80,6 +105,19 @@ krb5_copy_ticket(krb5_context context,
return 0;
}
+/**
+ * Return client principal in ticket
+ *
+ * @param context a Kerberos 5 context
+ * @param ticket ticket to copy
+ * @param client client principal, free with krb5_free_principal()
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_ticket_get_client(krb5_context context,
const krb5_ticket *ticket,
@@ -88,6 +126,19 @@ krb5_ticket_get_client(krb5_context context,
return krb5_copy_principal(context, ticket->client, client);
}
+/**
+ * Return server principal in ticket
+ *
+ * @param context a Kerberos 5 context
+ * @param ticket ticket to copy
+ * @param server server principal, free with krb5_free_principal()
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_ticket_get_server(krb5_context context,
const krb5_ticket *ticket,
@@ -96,6 +147,17 @@ krb5_ticket_get_server(krb5_context context,
return krb5_copy_principal(context, ticket->server, server);
}
+/**
+ * Return end time of ticket
+ *
+ * @param context a Kerberos 5 context
+ * @param ticket ticket to copy
+ *
+ * @return end time of ticket
+ *
+ * @ingroup krb5
+ */
+
time_t KRB5_LIB_FUNCTION
krb5_ticket_get_endtime(krb5_context context,
const krb5_ticket *ticket)
@@ -261,10 +323,17 @@ out:
return ret;
}
-/*
- * Extract the authorization data type of `type' from the
- * 'ticket'. Store the field in `data'. This function is to use for
- * kerberos applications.
+/**
+ * Extract the authorization data type of type from the ticket. Store
+ * the field in data. This function is to use for kerberos
+ * applications.
+ *
+ * @param context a Kerberos 5 context
+ * @param ticket Kerberos ticket
+ * @param type type to fetch
+ * @param data returned data, free with krb5_data_free()
+ *
+ * @ingroup krb5
*/
krb5_error_code KRB5_LIB_FUNCTION
diff --git a/source4/heimdal/lib/krb5/warn.c b/source4/heimdal/lib/krb5/warn.c
index b88b2004fb..05239186ec 100644
--- a/source4/heimdal/lib/krb5/warn.c
+++ b/source4/heimdal/lib/krb5/warn.c
@@ -269,7 +269,7 @@ krb5_vabort(krb5_context context, krb5_error_code code,
}
/**
- * Log a warning to the log, default stderr, include bthe error from
+ * Log a warning to the log, default stderr, include the error from
* the last failure and then abort.
*
* @param context A Kerberos 5 context
diff --git a/source4/heimdal/lib/ntlm/ntlm.c b/source4/heimdal/lib/ntlm/ntlm.c
index 1fe456d022..36a04f1ff2 100644
--- a/source4/heimdal/lib/ntlm/ntlm.c
+++ b/source4/heimdal/lib/ntlm/ntlm.c
@@ -875,22 +875,23 @@ splitandenc(unsigned char *hash,
unsigned char *challange,
unsigned char *answer)
{
- DES_cblock key;
- DES_key_schedule sched;
-
- ((unsigned char*)key)[0] = hash[0];
- ((unsigned char*)key)[1] = (hash[0] << 7) | (hash[1] >> 1);
- ((unsigned char*)key)[2] = (hash[1] << 6) | (hash[2] >> 2);
- ((unsigned char*)key)[3] = (hash[2] << 5) | (hash[3] >> 3);
- ((unsigned char*)key)[4] = (hash[3] << 4) | (hash[4] >> 4);
- ((unsigned char*)key)[5] = (hash[4] << 3) | (hash[5] >> 5);
- ((unsigned char*)key)[6] = (hash[5] << 2) | (hash[6] >> 6);
- ((unsigned char*)key)[7] = (hash[6] << 1);
-
- DES_set_odd_parity(&key);
- DES_set_key_unchecked(&key, &sched);
- DES_ecb_encrypt((DES_cblock *)challange, (DES_cblock *)answer, &sched, 1);
- memset(&sched, 0, sizeof(sched));
+ EVP_CIPHER_CTX ctx;
+ unsigned char key[8];
+
+ key[0] = hash[0];
+ key[1] = (hash[0] << 7) | (hash[1] >> 1);
+ key[2] = (hash[1] << 6) | (hash[2] >> 2);
+ key[3] = (hash[2] << 5) | (hash[3] >> 3);
+ key[4] = (hash[3] << 4) | (hash[4] >> 4);
+ key[5] = (hash[4] << 3) | (hash[5] >> 5);
+ key[6] = (hash[5] << 2) | (hash[6] >> 6);
+ key[7] = (hash[6] << 1);
+
+ EVP_CIPHER_CTX_init(&ctx);
+
+ EVP_CipherInit_ex(&ctx, EVP_des_cbc(), NULL, key, NULL, 1);
+ EVP_Cipher(&ctx, answer, challange, 8);
+ EVP_CIPHER_CTX_cleanup(&ctx);
memset(key, 0, sizeof(key));
}
@@ -910,7 +911,7 @@ int
heim_ntlm_nt_key(const char *password, struct ntlm_buf *key)
{
struct ntlm_buf buf;
- MD4_CTX ctx;
+ EVP_MD_CTX *m;
int ret;
key->data = malloc(MD5_DIGEST_LENGTH);
@@ -923,9 +924,19 @@ heim_ntlm_nt_key(const char *password, struct ntlm_buf *key)
heim_ntlm_free_buf(key);
return ret;
}
- MD4_Init(&ctx);
- MD4_Update(&ctx, buf.data, buf.length);
- MD4_Final(key->data, &ctx);
+
+ m = EVP_MD_CTX_create();
+ if (m == NULL) {
+ heim_ntlm_free_buf(key);
+ heim_ntlm_free_buf(&buf);
+ return ENOMEM;
+ }
+
+ EVP_DigestInit_ex(m, EVP_md4(), NULL);
+ EVP_DigestUpdate(m, buf.data, buf.length);
+ EVP_DigestFinal_ex(m, key->data, NULL);
+ EVP_MD_CTX_destroy(m);
+
heim_ntlm_free_buf(&buf);
return 0;
}
@@ -988,7 +999,7 @@ heim_ntlm_build_ntlm1_master(void *key, size_t len,
struct ntlm_buf *session,
struct ntlm_buf *master)
{
- RC4_KEY rc4;
+ EVP_CIPHER_CTX c;
memset(master, 0, sizeof(*master));
memset(session, 0, sizeof(*session));
@@ -1010,25 +1021,42 @@ heim_ntlm_build_ntlm1_master(void *key, size_t len,
return EINVAL;
}
+ EVP_CIPHER_CTX_init(&c);
+
{
unsigned char sessionkey[MD4_DIGEST_LENGTH];
- MD4_CTX ctx;
+ EVP_MD_CTX *m;
+
+ m = EVP_MD_CTX_create();
+ if (m == NULL) {
+ EVP_CIPHER_CTX_cleanup(&c);
+ heim_ntlm_free_buf(master);
+ heim_ntlm_free_buf(session);
+ return ENOMEM;
+ }
- MD4_Init(&ctx);
- MD4_Update(&ctx, key, len);
- MD4_Final(sessionkey, &ctx);
+ EVP_DigestInit_ex(m, EVP_md4(), NULL);
+ EVP_DigestUpdate(m, key, len);
+ EVP_DigestFinal_ex(m, sessionkey, NULL);
+ EVP_MD_CTX_destroy(m);
- RC4_set_key(&rc4, sizeof(sessionkey), sessionkey);
+ if (EVP_CipherInit_ex(&c, EVP_rc4(), NULL, sessionkey, NULL, 1) != 1) {
+ EVP_CIPHER_CTX_cleanup(&c);
+ heim_ntlm_free_buf(master);
+ heim_ntlm_free_buf(session);
+ return EINVAL;
+ }
}
if (RAND_bytes(session->data, session->length) != 1) {
+ EVP_CIPHER_CTX_cleanup(&c);
heim_ntlm_free_buf(master);
heim_ntlm_free_buf(session);
return EINVAL;
}
- RC4(&rc4, master->length, session->data, master->data);
- memset(&rc4, 0, sizeof(rc4));
+ EVP_Cipher(&c, master->data, session->data, master->length);
+ EVP_CIPHER_CTX_cleanup(&c);
return 0;
}
@@ -1349,15 +1377,22 @@ heim_ntlm_calculate_ntlm2_sess(const unsigned char clnt_nonce[8],
{
unsigned char ntlm2_sess_hash[MD5_DIGEST_LENGTH];
unsigned char res[21], *resp;
- MD5_CTX md5;
+ EVP_MD_CTX *m;
+
+ m = EVP_MD_CTX_create();
+ if (m == NULL)
+ return ENOMEM;
lm->data = malloc(24);
- if (lm->data == NULL)
+ if (lm->data == NULL) {
+ EVP_MD_CTX_destroy(m);
return ENOMEM;
+ }
lm->length = 24;
ntlm->data = malloc(24);
if (ntlm->data == NULL) {
+ EVP_MD_CTX_destroy(m);
free(lm->data);
lm->data = NULL;
return ENOMEM;
@@ -1368,10 +1403,11 @@ heim_ntlm_calculate_ntlm2_sess(const unsigned char clnt_nonce[8],
memset(lm->data, 0, 24);
memcpy(lm->data, clnt_nonce, 8);
- MD5_Init(&md5);
- MD5_Update(&md5, svr_chal, 8); /* session nonce part 1 */
- MD5_Update(&md5, clnt_nonce, 8); /* session nonce part 2 */
- MD5_Final(ntlm2_sess_hash, &md5); /* will only use first 8 bytes */
+ EVP_DigestInit_ex(m, EVP_md5(), NULL);
+ EVP_DigestUpdate(m, svr_chal, 8); /* session nonce part 1 */
+ EVP_DigestUpdate(m, clnt_nonce, 8); /* session nonce part 2 */
+ EVP_DigestFinal_ex(m, ntlm2_sess_hash, NULL); /* will only use first 8 bytes */
+ EVP_MD_CTX_destroy(m);
memset(res, 0, sizeof(res));
memcpy(res, ntlm_hash, 16);
diff --git a/source4/heimdal/lib/roken/base64.c b/source4/heimdal/lib/roken/base64.c
index bc74391b56..a9f0535dda 100644
--- a/source4/heimdal/lib/roken/base64.c
+++ b/source4/heimdal/lib/roken/base64.c
@@ -35,6 +35,7 @@
#include <stdlib.h>
#include <string.h>
+#include <limits.h>
#include "base64.h"
static const char base64_chars[] =
diff --git a/source4/heimdal/lib/roken/ct.c b/source4/heimdal/lib/roken/ct.c
new file mode 100644
index 0000000000..0778c2d474
--- /dev/null
+++ b/source4/heimdal/lib/roken/ct.c
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+#include <config.h>
+#include "roken.h"
+
+/**
+ * Constant time compare to memory regions. The reason for making it
+ * constant time is to make sure that timeing information leak from
+ * where in the function the diffrence is.
+ *
+ * ct_memcmp() can't be used to order memory regions like memcmp(),
+ * for example, use ct_memcmp() with qsort().
+ *
+ * @param p1 memory region 1 to compare
+ * @param p2 memory region 2 to compare
+ * @param len length of memory
+ *
+ * @return 0 when the memory regions are equal, non zero if not
+ *
+ * @ingroup roken
+ */
+
+int
+ct_memcmp(const void *p1, const void *p2, size_t len)
+{
+ const unsigned char *s1 = p1, *s2 = p2;
+ size_t i;
+ int r = 0;
+
+ for (i = 0; i < len; i++)
+ r |= (s1[i] ^ s2[i]);
+ return !!r;
+}
diff --git a/source4/heimdal/lib/roken/resolve.c b/source4/heimdal/lib/roken/resolve.c
index a74e438cf8..419c8d94e0 100644
--- a/source4/heimdal/lib/roken/resolve.c
+++ b/source4/heimdal/lib/roken/resolve.c
@@ -48,8 +48,6 @@
#include <assert.h>
-RCSID("$Id$");
-
#ifdef _AIX /* AIX have broken res_nsearch() in 5.1 (5.0 also ?) */
#undef HAVE_RES_NSEARCH
#endif
diff --git a/source4/heimdal/lib/roken/rkpty.c b/source4/heimdal/lib/roken/rkpty.c
index bff632f0f1..2776c1318b 100644
--- a/source4/heimdal/lib/roken/rkpty.c
+++ b/source4/heimdal/lib/roken/rkpty.c
@@ -120,7 +120,7 @@ open_pty(void)
strlcpy(line, ptsname(master), sizeof(line));
slave = open(line, O_RDWR);
if (slave < 0)
- errx(1, "failed to open slave when using %s", q);
+ errx(1, "failed to open slave when using %s", *q);
ioctl(slave, I_PUSH, "ptem");
ioctl(slave, I_PUSH, "ldterm");
diff --git a/source4/heimdal/lib/roken/roken-common.h b/source4/heimdal/lib/roken/roken-common.h
index 1713b6609e..ea7dcaade0 100644
--- a/source4/heimdal/lib/roken/roken-common.h
+++ b/source4/heimdal/lib/roken/roken-common.h
@@ -447,6 +447,8 @@ rk_cloexec(int);
void ROKEN_LIB_FUNCTION
rk_cloexec_file(FILE *);
+int ROKEN_LIB_FUNCTION
+ct_memcmp(const void *, const void *, size_t);
ROKEN_CPP_END
diff --git a/source4/heimdal/lib/roken/roken.h.in b/source4/heimdal/lib/roken/roken.h.in
index 3fce136875..2bd471736c 100644
--- a/source4/heimdal/lib/roken/roken.h.in
+++ b/source4/heimdal/lib/roken/roken.h.in
@@ -32,8 +32,6 @@
* SUCH DAMAGE.
*/
-/* $Id$ */
-
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
@@ -114,7 +112,7 @@ struct sockaddr_dl;
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
-#if defined(HAVE_SYS_IOCTL_H) && SunOS != 40
+#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#ifdef TIME_WITH_SYS_TIME
@@ -126,6 +124,10 @@ struct sockaddr_dl;
#include <time.h>
#endif
+#ifdef HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
@@ -309,7 +311,7 @@ char * ROKEN_LIB_FUNCTION strerror(int);
#define hstrerror rk_hstrerror
#endif
/* This causes a fatal error under Psoriasis */
-#if !(defined(SunOS) && (SunOS >= 50))
+#ifndef SunOS
const char * ROKEN_LIB_FUNCTION hstrerror(int);
#endif
#endif
@@ -337,7 +339,7 @@ int ROKEN_LIB_FUNCTION
inet_pton(int, const char *, void *);
#endif
-#if !defined(HAVE_GETCWD)
+#ifndef HAVE_GETCWD
#define getcwd rk_getcwd
char* ROKEN_LIB_FUNCTION getcwd(char *, size_t);
#endif
@@ -470,10 +472,14 @@ unsigned short ROKEN_LIB_FUNCTION bswap16(unsigned short);
#define LOCK_UN 8 /* Unlock */
#endif
-#define flock rk_flock
-int flock(int fd, int operation);
+#define flock(_x,_y) rk_flock(_x,_y)
+int rk_flock(int fd, int operation);
#endif /* HAVE_FLOCK */
+#ifdef SunOS
+#define dirfd(x) ((x)->dd_fd)
+#endif
+
time_t ROKEN_LIB_FUNCTION tm2time (struct tm, int);
int ROKEN_LIB_FUNCTION unix_verify_user(char *, char *);
@@ -677,26 +683,12 @@ char * ROKEN_LIB_FUNCTION estrdup (const char *);
* kludges and such
*/
-#if 1
int ROKEN_LIB_FUNCTION
roken_gethostby_setup(const char*, const char*);
struct hostent* ROKEN_LIB_FUNCTION
roken_gethostbyname(const char*);
struct hostent* ROKEN_LIB_FUNCTION
roken_gethostbyaddr(const void*, size_t, int);
-#else
-#ifdef GETHOSTBYNAME_PROTO_COMPATIBLE
-#define roken_gethostbyname(x) gethostbyname(x)
-#else
-#define roken_gethostbyname(x) gethostbyname((char *)x)
-#endif
-
-#ifdef GETHOSTBYADDR_PROTO_COMPATIBLE
-#define roken_gethostbyaddr(a, l, t) gethostbyaddr(a, l, t)
-#else
-#define roken_gethostbyaddr(a, l, t) gethostbyaddr((char *)a, l, t)
-#endif
-#endif
#ifdef GETSERVBYNAME_PROTO_COMPATIBLE
#define roken_getservbyname(x,y) getservbyname(x,y)
diff --git a/source4/heimdal/lib/roken/vis.c b/source4/heimdal/lib/roken/vis.c
index c8d19a4455..155b148e86 100644
--- a/source4/heimdal/lib/roken/vis.c
+++ b/source4/heimdal/lib/roken/vis.c
@@ -223,9 +223,9 @@ do_svis(char *dst, int c, int flag, int nextc, const char *extra)
}
if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) {
*dst++ = '\\';
- *dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0';
- *dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0';
- *dst++ = (c & 07) + '0';
+ *dst++ = (u_char)(((unsigned int)(u_char)c >> 6) & 03) + '0';
+ *dst++ = (u_char)(((unsigned int)(u_char)c >> 3) & 07) + '0';
+ *dst++ = (u_char)( c & 07) + '0';
} else {
if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\';
if (c & 0200) {
diff --git a/source4/heimdal/lib/wind/map.c b/source4/heimdal/lib/wind/map.c
index a005acccec..03f00de251 100644
--- a/source4/heimdal/lib/wind/map.c
+++ b/source4/heimdal/lib/wind/map.c
@@ -40,8 +40,6 @@
#include "map_table.h"
-RCSID("$Id$");
-
static int
translation_cmp(const void *key, const void *data)
{
diff --git a/source4/heimdal/lib/wind/normalize.c b/source4/heimdal/lib/wind/normalize.c
index 3f71449fac..4c70a52932 100644
--- a/source4/heimdal/lib/wind/normalize.c
+++ b/source4/heimdal/lib/wind/normalize.c
@@ -42,8 +42,6 @@
#include "normalize_table.h"
-RCSID("$Id$");
-
static int
translation_cmp(const void *key, const void *data)
{
diff --git a/source4/heimdal/lib/wind/stringprep.c b/source4/heimdal/lib/wind/stringprep.c
index aa04b3fd1d..a991f20cfb 100644
--- a/source4/heimdal/lib/wind/stringprep.c
+++ b/source4/heimdal/lib/wind/stringprep.c
@@ -39,8 +39,6 @@
#include <string.h>
#include <errno.h>
-RCSID("$Id$");
-
/**
* Process a input UCS4 string according a string-prep profile.
*
diff --git a/source4/heimdal/lib/wind/utf8.c b/source4/heimdal/lib/wind/utf8.c
index ed944b4c7d..d16683645c 100644
--- a/source4/heimdal/lib/wind/utf8.c
+++ b/source4/heimdal/lib/wind/utf8.c
@@ -34,8 +34,6 @@
#include <config.h>
#include "windlocl.h"
-RCSID("$Id$");
-
static int
utf8toutf32(const unsigned char **pp, uint32_t *out)
{