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
	 Love Hörnquist Åstrand
					Love Hörnquist Åstrand