more w2k compat from Luke Howard <lukeh@padl.com>
add RC2 support, clean up error messages git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@13762 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -111,6 +111,10 @@ static unsigned sha1WithRSAEncryption_num[] =
|
||||
{ 1, 2, 840, 113549, 1, 1, 5 };
|
||||
heim_oid heim_sha1WithRSAEncryption_oid =
|
||||
oid_enc(sha1WithRSAEncryption_num);
|
||||
static unsigned rc2CBC_num[] =
|
||||
{ 1, 2, 840, 113549, 3, 2 };
|
||||
heim_oid heim_rc2CBC_oid =
|
||||
oid_enc(rc2CBC_num);
|
||||
static unsigned des_ede3_cbc_num[] =
|
||||
{ 1, 2, 840, 113549, 3, 7 };
|
||||
heim_oid heim_des_ede3_cbc_oid =
|
||||
@@ -849,6 +853,7 @@ pk_verify_chain_standard(krb5_context context,
|
||||
X509_STORE_CTX_trusted_stack(store_ctx, id->trusted_certs);
|
||||
X509_verify_cert(store_ctx);
|
||||
/* the last checked certificate is in store_ctx->current_cert */
|
||||
krb5_clear_error_string(context);
|
||||
switch(store_ctx->error) {
|
||||
case X509_V_OK:
|
||||
ret = 0;
|
||||
@@ -864,12 +869,21 @@ pk_verify_chain_standard(krb5_context context,
|
||||
case X509_V_ERR_CERT_HAS_EXPIRED:
|
||||
ret = KRB5_KDC_ERR_INVALID_CERTIFICATE;
|
||||
break;
|
||||
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
|
||||
case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
|
||||
case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
|
||||
case X509_V_ERR_CERT_CHAIN_TOO_LONG:
|
||||
case X509_V_ERR_PATH_LENGTH_EXCEEDED:
|
||||
case X509_V_ERR_INVALID_CA:
|
||||
ret = KRB5_KDC_ERR_INVALID_CERTIFICATE;
|
||||
krb5_set_error_string(context, "unknown CA or can't "
|
||||
"verify certificate");
|
||||
break;
|
||||
default:
|
||||
ret = KRB5_KDC_ERR_INVALID_CERTIFICATE; /* XXX */
|
||||
break;
|
||||
}
|
||||
if (ret) {
|
||||
krb5_clear_error_string(context);
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -1123,6 +1137,7 @@ _krb5_pk_verify_sign(krb5_context context,
|
||||
|
||||
static krb5_error_code
|
||||
get_reply_key(krb5_context context,
|
||||
int win2k_compat,
|
||||
const heim_oid *eContentType,
|
||||
const krb5_data *eContent,
|
||||
unsigned nonce,
|
||||
@@ -1132,9 +1147,16 @@ get_reply_key(krb5_context context,
|
||||
krb5_error_code ret;
|
||||
size_t size;
|
||||
|
||||
if (heim_oid_cmp(eContentType, &heim_pkrkeydata_oid) != 0) {
|
||||
krb5_set_error_string(context, "PKINIT, reply key, wrong oid");
|
||||
return KRB5KRB_AP_ERR_MSG_TYPE;
|
||||
if (win2k_compat) {
|
||||
if (heim_oid_cmp(eContentType, &pkcs7_data_oid) != 0) {
|
||||
krb5_set_error_string(context, "PKINIT, reply key, wrong oid");
|
||||
return KRB5KRB_AP_ERR_MSG_TYPE;
|
||||
}
|
||||
} else {
|
||||
if (heim_oid_cmp(eContentType, &heim_pkrkeydata_oid) != 0) {
|
||||
krb5_set_error_string(context, "PKINIT, reply key, wrong oid");
|
||||
return KRB5KRB_AP_ERR_MSG_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
ret = decode_ReplyKeyPack(eContent->data,
|
||||
@@ -1148,6 +1170,7 @@ get_reply_key(krb5_context context,
|
||||
}
|
||||
|
||||
if (key_pack.nonce != nonce) {
|
||||
krb5_set_error_string(context, "PKINIT nonce is wrong");
|
||||
free_ReplyKeyPack(&key_pack);
|
||||
return KRB5KRB_AP_ERR_MODIFIED;
|
||||
}
|
||||
@@ -1163,7 +1186,7 @@ get_reply_key(krb5_context context,
|
||||
ret = copy_EncryptionKey(&key_pack.replyKey, *key);
|
||||
free_ReplyKeyPack(&key_pack);
|
||||
if (ret) {
|
||||
krb5_set_error_string(context, "PKINIT failed allocating reply key");
|
||||
krb5_set_error_string(context, "PKINIT failed copying reply key");
|
||||
free(*key);
|
||||
}
|
||||
|
||||
@@ -1201,6 +1224,9 @@ pk_rd_pa_reply_enckey(krb5_context context,
|
||||
krb5_data eContent;
|
||||
heim_oid eContentType = { 0, NULL };
|
||||
struct krb5_pk_cert *host = NULL;
|
||||
heim_octet_string encryptedContent;
|
||||
heim_octet_string *any;
|
||||
|
||||
|
||||
memset(&tmp_key, 0, sizeof(tmp_key));
|
||||
memset(&ed, 0, sizeof(ed));
|
||||
@@ -1246,7 +1272,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
|
||||
}
|
||||
|
||||
if (heim_oid_cmp(&heim_rsaEncryption_oid,
|
||||
&ri->keyEncryptionAlgorithm.algorithm)) {
|
||||
&ri->keyEncryptionAlgorithm.algorithm)) {
|
||||
krb5_set_error_string(context, "Invalid content type");
|
||||
return EINVAL;
|
||||
}
|
||||
@@ -1270,27 +1296,86 @@ pk_rd_pa_reply_enckey(krb5_context context,
|
||||
}
|
||||
}
|
||||
|
||||
if (ed.encryptedContentInfo.encryptedContent == NULL) {
|
||||
krb5_set_error_string(context, "OPTIONAL encryptedContent "
|
||||
"field not filled in in KDC reply");
|
||||
ret = KRB5_BADMSGTYPE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (heim_oid_cmp(&ed.encryptedContentInfo.contentEncryptionAlgorithm.algorithm,
|
||||
&heim_des_ede3_cbc_oid) == 0) {
|
||||
/* use des-ede3-cbc */
|
||||
heim_octet_string encryptedContent;
|
||||
heim_octet_string *any;
|
||||
any = ed.encryptedContentInfo.encryptedContent;
|
||||
ret = der_get_octet_string(any->data, any->length,
|
||||
&encryptedContent, NULL);
|
||||
if (ret) {
|
||||
krb5_set_error_string(context, "encryptedContent content invalid");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ed.encryptedContentInfo.encryptedContent == NULL) {
|
||||
krb5_set_error_string(context, "OPTIONAL encryptedContent "
|
||||
"field not filled in in KDC reply");
|
||||
if (heim_oid_cmp(&ed.encryptedContentInfo.contentEncryptionAlgorithm.algorithm, &heim_rc2CBC_oid) == 0) {
|
||||
/* use rc2-cbc */
|
||||
RC2CBCParameter params;
|
||||
int bits;
|
||||
|
||||
plain.data = malloc(encryptedContent.length);
|
||||
if (plain.data == NULL) {
|
||||
free_octet_string(&encryptedContent);
|
||||
krb5_set_error_string(context, "malloc - out of memory");
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
plain.length = encryptedContent.length;
|
||||
|
||||
ret = decode_RC2CBCParameter(ed.encryptedContentInfo.contentEncryptionAlgorithm.parameters->data,
|
||||
ed.encryptedContentInfo.contentEncryptionAlgorithm.parameters->length,
|
||||
¶ms,
|
||||
&size);
|
||||
if (ret) {
|
||||
free_octet_string(&encryptedContent);
|
||||
krb5_set_error_string(context, "failed decoding rc2 parameters");
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (params.rc2ParameterVersion) {
|
||||
case 160:
|
||||
bits = 40;
|
||||
break;
|
||||
case 120:
|
||||
bits = 64;
|
||||
break;
|
||||
case 58:
|
||||
bits = 128;
|
||||
break;
|
||||
default:
|
||||
krb5_set_error_string(context,
|
||||
"rc2ParameterVersion %d unsupported",
|
||||
params.rc2ParameterVersion);
|
||||
ret = KRB5_BADMSGTYPE;
|
||||
goto out;
|
||||
}
|
||||
if (params.iv.length != 8) {
|
||||
free_RC2CBCParameter(¶ms);
|
||||
krb5_set_error_string(context, "rc2 iv wrong size: %d",
|
||||
params.iv.length);
|
||||
ret = KRB5_BADMSGTYPE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
any = ed.encryptedContentInfo.encryptedContent;
|
||||
ret = der_get_octet_string(any->data, any->length,
|
||||
&encryptedContent, NULL);
|
||||
if (ret) {
|
||||
krb5_set_error_string(context, "encryptedContent content invalid");
|
||||
goto out;
|
||||
{
|
||||
RC2_KEY key;
|
||||
|
||||
RC2_set_key(&key, tmp_key.keyvalue.length,
|
||||
tmp_key.keyvalue.data, bits);
|
||||
|
||||
RC2_cbc_encrypt(encryptedContent.data,
|
||||
plain.data,
|
||||
encryptedContent.length, &key,
|
||||
params.iv.data, 0);
|
||||
}
|
||||
free_octet_string(&encryptedContent);
|
||||
|
||||
} else if (heim_oid_cmp(&ed.encryptedContentInfo.contentEncryptionAlgorithm.algorithm,
|
||||
&heim_des_ede3_cbc_oid) == 0) {
|
||||
/* use des-ede3-cbc */
|
||||
|
||||
tmp_key.keytype = ETYPE_DES3_CBC_NONE;
|
||||
ret = krb5_crypto_init(context,
|
||||
@@ -1333,7 +1418,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (heim_oid_cmp(&ci.contentType, &pkcs7_signed_oid) == 0) {
|
||||
if (heim_oid_cmp(&ci.contentType, &pkcs7_signed_oid)) {
|
||||
ret = EINVAL; /* XXX */
|
||||
krb5_set_error_string(context, "Invalid content type");
|
||||
goto out;
|
||||
@@ -1359,7 +1444,8 @@ pk_rd_pa_reply_enckey(krb5_context context,
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = get_reply_key(context, &eContentType, &eContent, nonce, key);
|
||||
ret = get_reply_key(context, win2k_compat,
|
||||
&eContentType, &eContent, nonce, key);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
|
Reference in New Issue
Block a user