14 * portion of this software, then the disclaimer below must
15 * also be included.
16 *
17 * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
18 * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
19 * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
20 * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
21 * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
23 * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
24 * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
25 * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
26 * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
27 * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGES.
29 */
30
31 /*
32 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
33 * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved.
34 */
35
36 #include <errno.h>
37 #include <string.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <dlfcn.h>
41 #include <unistd.h>
42 #include <dirent.h>
43
44
45 /* Solaris Kerberos */
46 #include <libintl.h>
47 #include <assert.h>
48 #include <security/pam_appl.h>
49 #include <ctype.h>
50 #include "k5-int.h"
51 #include <ctype.h>
52
53 /*
352 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
353 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
354 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
355 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
356 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
357 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
358 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
359 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
360 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
361 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
362 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
363 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
364 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
365 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
366 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
367 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
368 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
369 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
370 };
371
372 /* Solaris Kerberos */
373 static k5_mutex_t oids_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
374 static int pkinit_oids_refs = 0;
375
376 krb5_error_code
377 pkinit_init_plg_crypto(pkinit_plg_crypto_context *cryptoctx) {
378
379 krb5_error_code retval = ENOMEM;
380 pkinit_plg_crypto_context ctx = NULL;
381
382 /* initialize openssl routines */
383 /* Solaris Kerberos */
384 retval = openssl_init();
385 if (retval != 0)
386 goto out;
387
388 ctx = (pkinit_plg_crypto_context)malloc(sizeof(*ctx));
389 if (ctx == NULL)
390 goto out;
391 (void) memset(ctx, 0, sizeof(*ctx));
639 pkiDebug("failed to read private key from %s\n", filename);
640 goto cleanup;
641 }
642 *retkey = pkey;
643 retval = 0;
644 cleanup:
645 if (tmp != NULL)
646 BIO_free(tmp);
647 return retval;
648 }
649
650 static void
651 pkinit_fini_pkinit_oids(pkinit_plg_crypto_context ctx)
652 {
653 if (ctx == NULL)
654 return;
655
656 /* Only call OBJ_cleanup once! */
657 /* Solaris Kerberos: locking */
658 k5_mutex_lock(&oids_mutex);
659 if (--pkinit_oids_refs == 0)
660 OBJ_cleanup();
661 k5_mutex_unlock(&oids_mutex);
662 }
663
664 static krb5_error_code
665 pkinit_init_dh_params(pkinit_plg_crypto_context plgctx)
666 {
667 krb5_error_code retval = ENOMEM;
668
669 plgctx->dh_1024 = DH_new();
670 if (plgctx->dh_1024 == NULL)
671 goto cleanup;
672 plgctx->dh_1024->p = BN_bin2bn(pkinit_1024_dhprime,
673 sizeof(pkinit_1024_dhprime), NULL);
674 if ((plgctx->dh_1024->g = BN_new()) == NULL ||
675 (plgctx->dh_1024->q = BN_new()) == NULL)
676 goto cleanup;
677 BN_set_word(plgctx->dh_1024->g, DH_GENERATOR_2);
678 BN_rshift1(plgctx->dh_1024->q, plgctx->dh_1024->p);
679
680 plgctx->dh_2048 = DH_new();
681 if (plgctx->dh_2048 == NULL)
682 goto cleanup;
683 plgctx->dh_2048->p = BN_bin2bn(pkinit_2048_dhprime,
684 sizeof(pkinit_2048_dhprime), NULL);
685 if ((plgctx->dh_2048->g = BN_new()) == NULL ||
686 (plgctx->dh_2048->q = BN_new()) == NULL)
687 goto cleanup;
688 BN_set_word(plgctx->dh_2048->g, DH_GENERATOR_2);
689 BN_rshift1(plgctx->dh_2048->q, plgctx->dh_2048->p);
690
691 plgctx->dh_4096 = DH_new();
692 if (plgctx->dh_4096 == NULL)
693 goto cleanup;
694 plgctx->dh_4096->p = BN_bin2bn(pkinit_4096_dhprime,
695 sizeof(pkinit_4096_dhprime), NULL);
696 if ((plgctx->dh_4096->g = BN_new()) == NULL ||
697 (plgctx->dh_4096->q = BN_new()) == NULL)
698 goto cleanup;
699 BN_set_word(plgctx->dh_4096->g, DH_GENERATOR_2);
700 BN_rshift1(plgctx->dh_4096->q, plgctx->dh_4096->p);
701
702 retval = 0;
703
704 cleanup:
705 if (retval)
706 pkinit_fini_dh_params(plgctx);
707
708 return retval;
709 }
710
711 static void
712 pkinit_fini_dh_params(pkinit_plg_crypto_context plgctx)
713 {
714 if (plgctx->dh_1024 != NULL)
715 DH_free(plgctx->dh_1024);
716 if (plgctx->dh_2048 != NULL)
717 DH_free(plgctx->dh_2048);
718 if (plgctx->dh_4096 != NULL)
719 DH_free(plgctx->dh_4096);
720
841 cms_signeddata_create(krb5_context context,
842 pkinit_plg_crypto_context plg_cryptoctx,
843 pkinit_req_crypto_context req_cryptoctx,
844 pkinit_identity_crypto_context id_cryptoctx,
845 int cms_msg_type,
846 int include_certchain,
847 unsigned char *data,
848 unsigned int data_len,
849 unsigned char **signed_data,
850 unsigned int *signed_data_len)
851 {
852 /* Solaris Kerberos */
853 krb5_error_code retval = KRB5KRB_ERR_GENERIC;
854 PKCS7 *p7 = NULL, *inner_p7 = NULL;
855 PKCS7_SIGNED *p7s = NULL;
856 PKCS7_SIGNER_INFO *p7si = NULL;
857 unsigned char *p;
858 ASN1_TYPE *pkinit_data = NULL;
859 STACK_OF(X509) * cert_stack = NULL;
860 ASN1_OCTET_STRING *digest_attr = NULL;
861 EVP_MD_CTX ctx, ctx2;
862 const EVP_MD *md_tmp = NULL;
863 unsigned char md_data[EVP_MAX_MD_SIZE], md_data2[EVP_MAX_MD_SIZE];
864 unsigned char *digestInfo_buf = NULL, *abuf = NULL;
865 unsigned int md_len, md_len2, alen, digestInfo_len;
866 STACK_OF(X509_ATTRIBUTE) * sk;
867 unsigned char *sig = NULL;
868 unsigned int sig_len = 0;
869 X509_ALGOR *alg = NULL;
870 ASN1_OCTET_STRING *digest = NULL;
871 unsigned int alg_len = 0, digest_len = 0;
872 unsigned char *y = NULL, *alg_buf = NULL, *digest_buf = NULL;
873 X509 *cert = NULL;
874 ASN1_OBJECT *oid = NULL;
875
876 /* Solaris Kerberos */
877 if (signed_data == NULL)
878 return EINVAL;
879
880 if (signed_data_len == NULL)
881 return EINVAL;
885 goto cleanup;
886 p7->type = OBJ_nid2obj(NID_pkcs7_signed);
887
888 if ((p7s = PKCS7_SIGNED_new()) == NULL)
889 goto cleanup;
890 p7->d.sign = p7s;
891 if (!ASN1_INTEGER_set(p7s->version, 3))
892 goto cleanup;
893
894 /* create a cert chain that has at least the signer's certificate */
895 if ((cert_stack = sk_X509_new_null()) == NULL)
896 goto cleanup;
897
898 cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index);
899 if (!include_certchain) {
900 pkiDebug("only including signer's certificate\n");
901 sk_X509_push(cert_stack, X509_dup(cert));
902 } else {
903 /* create a cert chain */
904 X509_STORE *certstore = NULL;
905 X509_STORE_CTX certctx;
906 STACK_OF(X509) *certstack = NULL;
907 char buf[DN_BUF_LEN];
908 int i = 0, size = 0;
909
910 if ((certstore = X509_STORE_new()) == NULL)
911 goto cleanup;
912 pkiDebug("building certificate chain\n");
913 X509_STORE_set_verify_cb_func(certstore, openssl_callback);
914 X509_STORE_CTX_init(&certctx, certstore, cert,
915 id_cryptoctx->intermediateCAs);
916 X509_STORE_CTX_trusted_stack(&certctx, id_cryptoctx->trustedCAs);
917 /* Solaris Kerberos */
918 if (X509_verify_cert(&certctx) <= 0) {
919 pkiDebug("failed to create a certificate chain: %s\n",
920 X509_verify_cert_error_string(X509_STORE_CTX_get_error(&certctx)));
921 if (!sk_X509_num(id_cryptoctx->trustedCAs))
922 pkiDebug("No trusted CAs found. Check your X509_anchors\n");
923 goto cleanup;
924 }
925 certstack = X509_STORE_CTX_get1_chain(&certctx);
926 size = sk_X509_num(certstack);
927 pkiDebug("size of certificate chain = %d\n", size);
928 for(i = 0; i < size - 1; i++) {
929 X509 *x = sk_X509_value(certstack, i);
930 X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf));
931 pkiDebug("cert #%d: %s\n", i, buf);
932 sk_X509_push(cert_stack, X509_dup(x));
933 }
934 X509_STORE_CTX_cleanup(&certctx);
935 X509_STORE_free(certstore);
936 sk_X509_pop_free(certstack, X509_free);
937 }
938 p7s->cert = cert_stack;
939
940 /* fill-in PKCS7_SIGNER_INFO */
941 if ((p7si = PKCS7_SIGNER_INFO_new()) == NULL)
942 goto cleanup;
943 if (!ASN1_INTEGER_set(p7si->version, 1))
944 goto cleanup;
945 if (!X509_NAME_set(&p7si->issuer_and_serial->issuer,
946 X509_get_issuer_name(cert)))
947 goto cleanup;
948 /* because ASN1_INTEGER_set is used to set a 'long' we will do
949 * things the ugly way. */
950 M_ASN1_INTEGER_free(p7si->issuer_and_serial->serial);
951 if (!(p7si->issuer_and_serial->serial =
952 M_ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
953 goto cleanup;
954
955 /* will not fill-out EVP_PKEY because it's on the smartcard */
956
957 /* Set digest algs */
958 p7si->digest_alg->algorithm = OBJ_nid2obj(NID_sha1);
959
960 if (p7si->digest_alg->parameter != NULL)
961 ASN1_TYPE_free(p7si->digest_alg->parameter);
962 if ((p7si->digest_alg->parameter = ASN1_TYPE_new()) == NULL)
963 goto cleanup;
964 p7si->digest_alg->parameter->type = V_ASN1_NULL;
965
966 /* Set sig algs */
967 if (p7si->digest_enc_alg->parameter != NULL)
968 ASN1_TYPE_free(p7si->digest_enc_alg->parameter);
969 p7si->digest_enc_alg->algorithm = OBJ_nid2obj(NID_sha1WithRSAEncryption);
970 if (!(p7si->digest_enc_alg->parameter = ASN1_TYPE_new()))
971 goto cleanup;
972 p7si->digest_enc_alg->parameter->type = V_ASN1_NULL;
973
974 /* pick the correct oid for the eContentInfo */
975 oid = pkinit_pkcs7type2oid(plg_cryptoctx, cms_msg_type);
976 if (oid == NULL)
977 goto cleanup;
978
979 if (cms_msg_type == CMS_SIGN_DRAFT9) {
980 /* don't include signed attributes for pa-type 15 request */
981 abuf = data;
982 alen = data_len;
983 } else {
984 /* add signed attributes */
985 /* compute sha1 digest over the EncapsulatedContentInfo */
986 EVP_MD_CTX_init(&ctx);
987 EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL);
988 EVP_DigestUpdate(&ctx, data, data_len);
989 md_tmp = EVP_MD_CTX_md(&ctx);
990 EVP_DigestFinal_ex(&ctx, md_data, &md_len);
991
992 /* create a message digest attr */
993 digest_attr = ASN1_OCTET_STRING_new();
994 ASN1_OCTET_STRING_set(digest_attr, md_data, (int)md_len);
995 PKCS7_add_signed_attribute(p7si, NID_pkcs9_messageDigest,
996 V_ASN1_OCTET_STRING, (char *) digest_attr);
997
998 /* create a content-type attr */
999 PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType,
1000 V_ASN1_OBJECT, oid);
1001
1002 /* create the signature over signed attributes. get DER encoded value */
1003 /* This is the place where smartcard signature needs to be calculated */
1004 sk = p7si->auth_attr;
1005 alen = ASN1_item_i2d((ASN1_VALUE *) sk, &abuf,
1006 ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
1007 if (abuf == NULL)
1008 goto cleanup2;
1009 }
1010
1011 #ifndef WITHOUT_PKCS11
1012 /* Some tokens can only do RSAEncryption without sha1 hash */
1013 /* to compute sha1WithRSAEncryption, encode the algorithm ID for the hash
1014 * function and the hash value into an ASN.1 value of type DigestInfo
1015 * DigestInfo::=SEQUENCE {
1016 * digestAlgorithm AlgorithmIdentifier,
1017 * digest OCTET STRING }
1018 */
1019 if (id_cryptoctx->pkcs11_method == 1 &&
1020 id_cryptoctx->mech == CKM_RSA_PKCS) {
1021 pkiDebug("mech = CKM_RSA_PKCS\n");
1022 EVP_MD_CTX_init(&ctx2);
1023 /* if this is not draft9 request, include digest signed attribute */
1024 if (cms_msg_type != CMS_SIGN_DRAFT9)
1025 EVP_DigestInit_ex(&ctx2, md_tmp, NULL);
1026 else
1027 EVP_DigestInit_ex(&ctx2, EVP_sha1(), NULL);
1028 EVP_DigestUpdate(&ctx2, abuf, alen);
1029 EVP_DigestFinal_ex(&ctx2, md_data2, &md_len2);
1030
1031 alg = X509_ALGOR_new();
1032 if (alg == NULL)
1033 goto cleanup2;
1034 alg->algorithm = OBJ_nid2obj(NID_sha1);
1035 alg->parameter = NULL;
1036 alg_len = i2d_X509_ALGOR(alg, NULL);
1037 alg_buf = (unsigned char *)malloc(alg_len);
1038 if (alg_buf == NULL)
1039 goto cleanup2;
1040
1041 digest = ASN1_OCTET_STRING_new();
1042 if (digest == NULL)
1043 goto cleanup2;
1044 ASN1_OCTET_STRING_set(digest, md_data2, (int)md_len2);
1045 digest_len = i2d_ASN1_OCTET_STRING(digest, NULL);
1046 digest_buf = (unsigned char *)malloc(digest_len);
1047 if (digest_buf == NULL)
1048 goto cleanup2;
1049
1143 }
1144 retval = 0;
1145
1146 #ifdef DEBUG_ASN1
1147 if (cms_msg_type == CMS_SIGN_CLIENT) {
1148 print_buffer_bin(*signed_data, *signed_data_len,
1149 "/tmp/client_pkcs7_signeddata");
1150 } else {
1151 if (cms_msg_type == CMS_SIGN_SERVER) {
1152 print_buffer_bin(*signed_data, *signed_data_len,
1153 "/tmp/kdc_pkcs7_signeddata");
1154 } else {
1155 print_buffer_bin(*signed_data, *signed_data_len,
1156 "/tmp/draft9_pkcs7_signeddata");
1157 }
1158 }
1159 #endif
1160
1161 cleanup2:
1162 if (cms_msg_type != CMS_SIGN_DRAFT9)
1163 EVP_MD_CTX_cleanup(&ctx);
1164 #ifndef WITHOUT_PKCS11
1165 if (id_cryptoctx->pkcs11_method == 1 &&
1166 id_cryptoctx->mech == CKM_RSA_PKCS) {
1167 EVP_MD_CTX_cleanup(&ctx2);
1168 if (digest_buf != NULL)
1169 free(digest_buf);
1170 if (digestInfo_buf != NULL)
1171 free(digestInfo_buf);
1172 if (alg_buf != NULL)
1173 free(alg_buf);
1174 if (digest != NULL)
1175 ASN1_OCTET_STRING_free(digest);
1176 }
1177 #endif
1178 if (alg != NULL)
1179 X509_ALGOR_free(alg);
1180 cleanup:
1181 if (p7 != NULL)
1182 PKCS7_free(p7);
1183 if (sig != NULL)
1184 free(sig);
1185
1186 return retval;
1187 }
1193 pkinit_identity_crypto_context idctx,
1194 int cms_msg_type,
1195 int require_crl_checking,
1196 unsigned char *signed_data,
1197 unsigned int signed_data_len,
1198 unsigned char **data,
1199 unsigned int *data_len,
1200 unsigned char **authz_data,
1201 unsigned int *authz_data_len)
1202 {
1203 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
1204 PKCS7 *p7 = NULL;
1205 BIO *out = NULL;
1206 int flags = PKCS7_NOVERIFY, i = 0;
1207 unsigned int vflags = 0, size = 0;
1208 const unsigned char *p = signed_data;
1209 STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
1210 PKCS7_SIGNER_INFO *si = NULL;
1211 X509 *x = NULL;
1212 X509_STORE *store = NULL;
1213 X509_STORE_CTX cert_ctx;
1214 STACK_OF(X509) *intermediateCAs = NULL;
1215 STACK_OF(X509_CRL) *revoked = NULL;
1216 STACK_OF(X509) *verified_chain = NULL;
1217 ASN1_OBJECT *oid = NULL;
1218 krb5_external_principal_identifier **krb5_verified_chain = NULL;
1219 krb5_data *authz = NULL;
1220 char buf[DN_BUF_LEN];
1221
1222 #ifdef DEBUG_ASN1
1223 print_buffer_bin(signed_data, signed_data_len,
1224 "/tmp/client_received_pkcs7_signeddata");
1225 #endif
1226
1227 /* Do this early enough to create the shadow OID for pkcs7-data if needed */
1228 oid = pkinit_pkcs7type2oid(plgctx, cms_msg_type);
1229 if (oid == NULL)
1230 goto cleanup;
1231
1232 /* decode received PKCS7 message */
1233 if ((p7 = d2i_PKCS7(NULL, &p, (int)signed_data_len)) == NULL) {
1237 pkiDebug("%s: failed to decode message: %s\n",
1238 __FUNCTION__, ERR_error_string(err, NULL));
1239 goto cleanup;
1240 }
1241
1242 /* verify that the received message is PKCS7 SignedData message */
1243 if (OBJ_obj2nid(p7->type) != NID_pkcs7_signed) {
1244 pkiDebug("Expected id-signedData PKCS7 msg (received type = %d)\n",
1245 OBJ_obj2nid(p7->type));
1246 krb5_set_error_message(context, retval, "wrong oid\n");
1247 goto cleanup;
1248 }
1249
1250 /* setup to verify X509 certificate used to sign PKCS7 message */
1251 if (!(store = X509_STORE_new()))
1252 goto cleanup;
1253
1254 /* check if we are inforcing CRL checking */
1255 vflags = X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
1256 if (require_crl_checking)
1257 X509_STORE_set_verify_cb_func(store, openssl_callback);
1258 else
1259 X509_STORE_set_verify_cb_func(store, openssl_callback_ignore_crls);
1260 X509_STORE_set_flags(store, vflags);
1261
1262 /* get the signer's information from the PKCS7 message */
1263 if ((si_sk = PKCS7_get_signer_info(p7)) == NULL)
1264 goto cleanup;
1265 if ((si = sk_PKCS7_SIGNER_INFO_value(si_sk, 0)) == NULL)
1266 goto cleanup;
1267 if ((x = PKCS7_cert_from_signer_info(p7, si)) == NULL)
1268 goto cleanup;
1269
1270 /* create available CRL information (get local CRLs and include CRLs
1271 * received in the PKCS7 message
1272 */
1273 if (idctx->revoked == NULL)
1274 revoked = p7->d.sign->crl;
1275 else if (p7->d.sign->crl == NULL)
1276 revoked = idctx->revoked;
1277 else {
1278 size = sk_X509_CRL_num(idctx->revoked);
1279 revoked = sk_X509_CRL_new_null();
1290 if (idctx->intermediateCAs == NULL)
1291 intermediateCAs = p7->d.sign->cert;
1292 else if (p7->d.sign->cert == NULL)
1293 intermediateCAs = idctx->intermediateCAs;
1294 else {
1295 size = sk_X509_num(idctx->intermediateCAs);
1296 intermediateCAs = sk_X509_new_null();
1297 for (i = 0; i < size; i++) {
1298 sk_X509_push(intermediateCAs,
1299 sk_X509_value(idctx->intermediateCAs, i));
1300 }
1301 size = sk_X509_num(p7->d.sign->cert);
1302 for (i = 0; i < size; i++) {
1303 sk_X509_push(intermediateCAs, sk_X509_value(p7->d.sign->cert, i));
1304 }
1305 }
1306
1307 /* initialize x509 context with the received certificate and
1308 * trusted and intermediate CA chains and CRLs
1309 */
1310 if (!X509_STORE_CTX_init(&cert_ctx, store, x, intermediateCAs))
1311 goto cleanup;
1312
1313 X509_STORE_CTX_set0_crls(&cert_ctx, revoked);
1314
1315 /* add trusted CAs certificates for cert verification */
1316 if (idctx->trustedCAs != NULL)
1317 X509_STORE_CTX_trusted_stack(&cert_ctx, idctx->trustedCAs);
1318 else {
1319 pkiDebug("unable to find any trusted CAs\n");
1320 goto cleanup;
1321 }
1322 #ifdef DEBUG_CERTCHAIN
1323 if (intermediateCAs != NULL) {
1324 size = sk_X509_num(intermediateCAs);
1325 pkiDebug("untrusted cert chain of size %d\n", size);
1326 for (i = 0; i < size; i++) {
1327 X509_NAME_oneline(X509_get_subject_name(
1328 sk_X509_value(intermediateCAs, i)), buf, sizeof(buf));
1329 pkiDebug("cert #%d: %s\n", i, buf);
1330 }
1331 }
1332 if (idctx->trustedCAs != NULL) {
1333 size = sk_X509_num(idctx->trustedCAs);
1334 pkiDebug("trusted cert chain of size %d\n", size);
1335 for (i = 0; i < size; i++) {
1336 X509_NAME_oneline(X509_get_subject_name(
1337 sk_X509_value(idctx->trustedCAs, i)), buf, sizeof(buf));
1338 pkiDebug("cert #%d: %s\n", i, buf);
1339 }
1340 }
1341 if (revoked != NULL) {
1342 size = sk_X509_CRL_num(revoked);
1343 pkiDebug("CRL chain of size %d\n", size);
1344 for (i = 0; i < size; i++) {
1345 X509_CRL *crl = sk_X509_CRL_value(revoked, i);
1346 X509_NAME_oneline(X509_CRL_get_issuer(crl), buf, sizeof(buf));
1347 pkiDebug("crls by CA #%d: %s\n", i , buf);
1348 }
1349 }
1350 #endif
1351
1352 i = X509_verify_cert(&cert_ctx);
1353 if (i <= 0) {
1354 int j = X509_STORE_CTX_get_error(&cert_ctx);
1355
1356 reqctx->received_cert = X509_dup(cert_ctx.current_cert);
1357 switch(j) {
1358 case X509_V_ERR_CERT_REVOKED:
1359 retval = KRB5KDC_ERR_REVOKED_CERTIFICATE;
1360 break;
1361 case X509_V_ERR_UNABLE_TO_GET_CRL:
1362 retval = KRB5KDC_ERR_REVOCATION_STATUS_UNKNOWN;
1363 break;
1364 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
1365 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1366 retval = KRB5KDC_ERR_CANT_VERIFY_CERTIFICATE;
1367 break;
1368 default:
1369 retval = KRB5KDC_ERR_INVALID_CERTIFICATE;
1370 }
1371 X509_NAME_oneline(X509_get_subject_name(
1372 reqctx->received_cert), buf, sizeof(buf));
1373 pkiDebug("problem with cert DN = %s (error=%d) %s\n", buf, j,
1374 X509_verify_cert_error_string(j));
1375 krb5_set_error_message(context, retval, "%s\n",
1376 X509_verify_cert_error_string(j));
1377 #ifdef DEBUG_CERTCHAIN
1378 size = sk_X509_num(p7->d.sign->cert);
1379 pkiDebug("received cert chain of size %d\n", size);
1380 for (j = 0; j < size; j++) {
1381 X509 *tmp_cert = sk_X509_value(p7->d.sign->cert, j);
1382 X509_NAME_oneline(X509_get_subject_name(tmp_cert), buf, sizeof(buf));
1383 pkiDebug("cert #%d: %s\n", j, buf);
1384 }
1385 #endif
1386 } else {
1387 /* retrieve verified certificate chain */
1388 if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9)
1389 verified_chain = X509_STORE_CTX_get1_chain(&cert_ctx);
1390 }
1391 X509_STORE_CTX_cleanup(&cert_ctx);
1392 if (i <= 0)
1393 goto cleanup;
1394
1395 out = BIO_new(BIO_s_mem());
1396 if (cms_msg_type == CMS_SIGN_DRAFT9)
1397 flags |= PKCS7_NOATTR;
1398 if (PKCS7_verify(p7, NULL, store, NULL, out, flags)) {
1399 int valid_oid = 0;
1400
1401 if (!OBJ_cmp(p7->d.sign->contents->type, oid))
1402 valid_oid = 1;
1403 else if (cms_msg_type == CMS_SIGN_DRAFT9) {
1404 /*
1405 * Various implementations of the pa-type 15 request use
1406 * different OIDS. We check that the returned object
1407 * has any of the acceptable OIDs
1408 */
1409 ASN1_OBJECT *client_oid = NULL, *server_oid = NULL, *rsa_oid = NULL;
1410 client_oid = pkinit_pkcs7type2oid(plgctx, CMS_SIGN_CLIENT);
1411 server_oid = pkinit_pkcs7type2oid(plgctx, CMS_SIGN_SERVER);
1412 rsa_oid = pkinit_pkcs7type2oid(plgctx, CMS_ENVEL_SERVER);
1413 if (!OBJ_cmp(p7->d.sign->contents->type, client_oid) ||
1414 !OBJ_cmp(p7->d.sign->contents->type, server_oid) ||
1415 !OBJ_cmp(p7->d.sign->contents->type, rsa_oid))
1416 valid_oid = 1;
1417 }
1418
1419 if (valid_oid)
1420 pkiDebug("PKCS7 Verification successful\n");
1421 else {
1422 pkiDebug("wrong oid in eContentType\n");
1423 print_buffer((unsigned char *)p7->d.sign->contents->type->data,
1424 (unsigned int)p7->d.sign->contents->type->length);
1425 retval = KRB5KDC_ERR_PREAUTH_FAILED;
1426 krb5_set_error_message(context, retval, "wrong oid\n");
1427 goto cleanup;
1428 }
1429 }
1430 else {
1431 unsigned long err = ERR_peek_error();
1432 switch(ERR_GET_REASON(err)) {
1433 case PKCS7_R_DIGEST_FAILURE:
1434 retval = KRB5KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED;
1435 break;
1436 case PKCS7_R_SIGNATURE_FAILURE:
1437 default:
1438 retval = KRB5KDC_ERR_INVALID_SIG;
1439 }
1440 pkiDebug("PKCS7 Verification failure\n");
1441 krb5_set_error_message(context, retval, "%s\n",
1442 ERR_error_string(err, NULL));
1443 goto cleanup;
1444 }
2146 }
2147
2148 return retval;
2149 }
2150
2151 /* ARGSUSED */
2152 krb5_error_code
2153 client_create_dh(krb5_context context,
2154 pkinit_plg_crypto_context plg_cryptoctx,
2155 pkinit_req_crypto_context cryptoctx,
2156 pkinit_identity_crypto_context id_cryptoctx,
2157 int dh_size,
2158 unsigned char **dh_params,
2159 unsigned int *dh_params_len,
2160 unsigned char **dh_pubkey,
2161 unsigned int *dh_pubkey_len)
2162 {
2163 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
2164 unsigned char *buf = NULL;
2165 int dh_err = 0;
2166 ASN1_INTEGER *pub_key = NULL;
2167
2168 if (cryptoctx->dh == NULL) {
2169 if ((cryptoctx->dh = DH_new()) == NULL)
2170 goto cleanup;
2171 if ((cryptoctx->dh->g = BN_new()) == NULL ||
2172 (cryptoctx->dh->q = BN_new()) == NULL)
2173 goto cleanup;
2174
2175 switch(dh_size) {
2176 case 1024:
2177 pkiDebug("client uses 1024 DH keys\n");
2178 cryptoctx->dh->p = get_rfc2409_prime_1024(NULL);
2179 break;
2180 case 2048:
2181 pkiDebug("client uses 2048 DH keys\n");
2182 cryptoctx->dh->p = BN_bin2bn(pkinit_2048_dhprime,
2183 sizeof(pkinit_2048_dhprime), NULL);
2184 break;
2185 case 4096:
2186 pkiDebug("client uses 4096 DH keys\n");
2187 cryptoctx->dh->p = BN_bin2bn(pkinit_4096_dhprime,
2188 sizeof(pkinit_4096_dhprime), NULL);
2189 break;
2190 default:
2191 goto cleanup;
2192 }
2193
2194 BN_set_word((cryptoctx->dh->g), DH_GENERATOR_2);
2195 BN_rshift1(cryptoctx->dh->q, cryptoctx->dh->p);
2196 }
2197
2198 DH_generate_key(cryptoctx->dh);
2199 /* Solaris Kerberos */
2200 #ifdef DEBUG
2201 DH_check(cryptoctx->dh, &dh_err);
2202 if (dh_err != 0) {
2203 pkiDebug("Warning: dh_check failed with %d\n", dh_err);
2204 if (dh_err & DH_CHECK_P_NOT_PRIME)
2205 pkiDebug("p value is not prime\n");
2206 if (dh_err & DH_CHECK_P_NOT_SAFE_PRIME)
2207 pkiDebug("p value is not a safe prime\n");
2208 if (dh_err & DH_UNABLE_TO_CHECK_GENERATOR)
2209 pkiDebug("unable to check the generator value\n");
2210 if (dh_err & DH_NOT_SUITABLE_GENERATOR)
2211 pkiDebug("the g value is not a generator\n");
2212 }
2213 #endif
2214 #ifdef DEBUG_DH
2215 print_dh(cryptoctx->dh, "client's DH params\n");
2216 print_pubkey(cryptoctx->dh->pub_key, "client's pub_key=");
2217 #endif
2218
2219 DH_check_pub_key(cryptoctx->dh, cryptoctx->dh->pub_key, &dh_err);
2220 if (dh_err != 0) {
2221 pkiDebug("dh_check_pub_key failed with %d\n", dh_err);
2222 goto cleanup;
2223 }
2224
2225 /* pack DHparams */
2226 /* aglo: usually we could just call i2d_DHparams to encode DH params
2227 * however, PKINIT requires RFC3279 encoding and openssl does pkcs#3.
2228 */
2229 retval = pkinit_encode_dh_params(cryptoctx->dh->p, cryptoctx->dh->g,
2230 cryptoctx->dh->q, dh_params, dh_params_len);
2231 if (retval)
2232 goto cleanup;
2233
2234 /* pack DH public key */
2235 /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this
2236 * encoding shall be used as the contents (the value) of the
2237 * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo
2238 * data element
2239 */
2240 if ((pub_key = BN_to_ASN1_INTEGER(cryptoctx->dh->pub_key, NULL)) == NULL)
2241 goto cleanup;
2242 *dh_pubkey_len = i2d_ASN1_INTEGER(pub_key, NULL);
2243 if ((buf = *dh_pubkey = (unsigned char *)
2244 malloc((size_t) *dh_pubkey_len)) == NULL) {
2245 retval = ENOMEM;
2246 goto cleanup;
2247 }
2248 i2d_ASN1_INTEGER(pub_key, &buf);
2249
2250 if (pub_key != NULL)
2251 ASN1_INTEGER_free(pub_key);
2252
2253 retval = 0;
2254 return retval;
2255
2256 cleanup:
2257 if (cryptoctx->dh != NULL)
2258 DH_free(cryptoctx->dh);
2259 cryptoctx->dh = NULL;
2260 if (*dh_params != NULL)
2261 free(*dh_params);
2262 *dh_params = NULL;
2263 if (*dh_pubkey != NULL)
2264 free(*dh_pubkey);
2265 *dh_pubkey = NULL;
2266 if (pub_key != NULL)
2267 ASN1_INTEGER_free(pub_key);
2268
2269 return retval;
2270 }
2271
2272 /* ARGSUSED */
2273 krb5_error_code
2274 client_process_dh(krb5_context context,
2275 pkinit_plg_crypto_context plg_cryptoctx,
2276 pkinit_req_crypto_context cryptoctx,
2277 pkinit_identity_crypto_context id_cryptoctx,
2278 unsigned char *subjectPublicKey_data,
2279 unsigned int subjectPublicKey_length,
2280 unsigned char **client_key,
2281 unsigned int *client_key_len)
2282 {
2283 /* Solaris Kerberos */
2284 krb5_error_code retval = KRB5_PREAUTH_FAILED;
2285 BIGNUM *server_pub_key = NULL;
2286 ASN1_INTEGER *pub_key = NULL;
2287 const unsigned char *p = NULL;
2335 ASN1_INTEGER_free(pub_key);
2336 if (data != NULL)
2337 free (data);
2338
2339 return retval;
2340 }
2341
2342 /* ARGSUSED */
2343 krb5_error_code
2344 server_check_dh(krb5_context context,
2345 pkinit_plg_crypto_context cryptoctx,
2346 pkinit_req_crypto_context req_cryptoctx,
2347 pkinit_identity_crypto_context id_cryptoctx,
2348 krb5_octet_data *dh_params,
2349 int minbits)
2350 {
2351 DH *dh = NULL;
2352 unsigned char *tmp = NULL;
2353 int dh_prime_bits;
2354 krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
2355
2356 tmp = dh_params->data;
2357 dh = DH_new();
2358 dh = pkinit_decode_dh_params(&dh, &tmp, dh_params->length);
2359 if (dh == NULL) {
2360 pkiDebug("failed to decode dhparams\n");
2361 goto cleanup;
2362 }
2363
2364 /* KDC SHOULD check to see if the key parameters satisfy its policy */
2365 dh_prime_bits = BN_num_bits(dh->p);
2366 if (minbits && dh_prime_bits < minbits) {
2367 pkiDebug("client sent dh params with %d bits, we require %d\n",
2368 dh_prime_bits, minbits);
2369 goto cleanup;
2370 }
2371
2372 /* check dhparams is group 2 */
2373 if (pkinit_check_dh_params(cryptoctx->dh_1024->p,
2374 dh->p, dh->g, dh->q) == 0) {
2375 retval = 0;
2376 goto cleanup;
2377 }
2378
2379 /* check dhparams is group 14 */
2380 if (pkinit_check_dh_params(cryptoctx->dh_2048->p,
2381 dh->p, dh->g, dh->q) == 0) {
2382 retval = 0;
2383 goto cleanup;
2384 }
2385
2386 /* check dhparams is group 16 */
2387 if (pkinit_check_dh_params(cryptoctx->dh_4096->p,
2388 dh->p, dh->g, dh->q) == 0) {
2389 retval = 0;
2390 goto cleanup;
2391 }
2392
2393 cleanup:
2394 if (retval == 0)
2395 req_cryptoctx->dh = dh;
2396 else
2397 DH_free(dh);
2398
2399 return retval;
2400 }
2401
2402 /* kdc's dh function */
2403 /* ARGSUSED */
2404 krb5_error_code
2405 server_process_dh(krb5_context context,
2406 pkinit_plg_crypto_context plg_cryptoctx,
2407 pkinit_req_crypto_context cryptoctx,
2408 pkinit_identity_crypto_context id_cryptoctx,
2409 unsigned char *data,
2410 unsigned int data_len,
2411 unsigned char **dh_pubkey,
2412 unsigned int *dh_pubkey_len,
2413 unsigned char **server_key,
2414 unsigned int *server_key_len)
2415 {
2416 /* Solaris Kerberos */
2417 krb5_error_code retval = KRB5KRB_ERR_GENERIC;
2418 DH *dh = NULL, *dh_server = NULL;
2419 unsigned char *p = NULL;
2420 ASN1_INTEGER *pub_key = NULL;
2421
2422 /* get client's received DH parameters that we saved in server_check_dh */
2423 dh = cryptoctx->dh;
2424
2425 dh_server = DH_new();
2426 if (dh_server == NULL)
2427 goto cleanup;
2428 dh_server->p = BN_dup(dh->p);
2429 dh_server->g = BN_dup(dh->g);
2430 dh_server->q = BN_dup(dh->q);
2431
2432 /* decode client's public key */
2433 p = data;
2434 pub_key = d2i_ASN1_INTEGER(NULL, (const unsigned char **)&p, (int)data_len);
2435 if (pub_key == NULL)
2436 goto cleanup;
2437 dh->pub_key = ASN1_INTEGER_to_BN(pub_key, NULL);
2438 if (dh->pub_key == NULL)
2439 goto cleanup;
2440 ASN1_INTEGER_free(pub_key);
2441
2442 if (!DH_generate_key(dh_server))
2443 goto cleanup;
2444
2445 /* generate DH session key */
2446 *server_key_len = DH_size(dh_server);
2447 if ((*server_key = (unsigned char *) malloc((size_t)*server_key_len)) == NULL)
2448 goto cleanup;
2449 DH_compute_key(*server_key, dh->pub_key, dh_server);
2450
2451 #ifdef DEBUG_DH
2452 print_dh(dh_server, "client&server's DH params\n");
2453 print_pubkey(dh->pub_key, "client's pub_key=");
2454 print_pubkey(dh_server->pub_key, "server's pub_key=");
2455 pkiDebug("server secret key=");
2456 print_buffer(*server_key, *server_key_len);
2457 #endif
2458
2459 /* KDC reply */
2460 /* pack DH public key */
2461 /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this
2462 * encoding shall be used as the contents (the value) of the
2463 * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo
2464 * data element
2465 */
2466 if ((pub_key = BN_to_ASN1_INTEGER(dh_server->pub_key, NULL)) == NULL)
2467 goto cleanup;
2468 *dh_pubkey_len = i2d_ASN1_INTEGER(pub_key, NULL);
2469 if ((p = *dh_pubkey = (unsigned char *) malloc((size_t)*dh_pubkey_len)) == NULL)
2470 goto cleanup;
2471 i2d_ASN1_INTEGER(pub_key, &p);
2472 if (pub_key != NULL)
2473 ASN1_INTEGER_free(pub_key);
2474
2475 retval = 0;
2476
2477 if (dh_server != NULL)
2478 DH_free(dh_server);
2479 return retval;
2480
2481 cleanup:
2482 if (dh_server != NULL)
2483 DH_free(dh_server);
2484 if (*dh_pubkey != NULL)
2485 free(*dh_pubkey);
2486 if (*server_key != NULL)
2487 free(*server_key);
2488
2489 return retval;
2490 }
2491
2492 /*
2493 * Solaris Kerberos:
2494 * Add locking around did_init to make it MT-safe.
2495 */
2496 static krb5_error_code
2497 openssl_init()
2498 {
2499 krb5_error_code ret = 0;
2500 static int did_init = 0;
2501 static k5_mutex_t init_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
2502
2503 ret = k5_mutex_lock(&init_mutex);
2504 if (ret == 0) {
2505 if (!did_init) {
2506 /* initialize openssl routines */
2507 CRYPTO_malloc_init();
2508 ERR_load_crypto_strings();
2509 OpenSSL_add_all_algorithms();
2510 did_init++;
2511 }
2512 k5_mutex_unlock(&init_mutex);
2513 }
2514 return (ret);
2515 }
2516
2517 static krb5_error_code
2518 pkinit_encode_dh_params(BIGNUM *p, BIGNUM *g, BIGNUM *q,
2519 unsigned char **buf, unsigned int *buf_len)
2520 {
2521 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
2522 int bufsize = 0, r = 0;
2523 unsigned char *tmp = NULL;
2524 ASN1_INTEGER *ap = NULL, *ag = NULL, *aq = NULL;
2525
2526 if ((ap = BN_to_ASN1_INTEGER(p, NULL)) == NULL)
2527 goto cleanup;
2528 if ((ag = BN_to_ASN1_INTEGER(g, NULL)) == NULL)
2529 goto cleanup;
2530 if ((aq = BN_to_ASN1_INTEGER(q, NULL)) == NULL)
2531 goto cleanup;
2532 bufsize = i2d_ASN1_INTEGER(ap, NULL);
2533 bufsize += i2d_ASN1_INTEGER(ag, NULL);
2534 bufsize += i2d_ASN1_INTEGER(aq, NULL);
2535
2536 r = ASN1_object_size(1, bufsize, V_ASN1_SEQUENCE);
2537
2538 tmp = *buf = (unsigned char *)malloc((size_t) r);
2543
2544 i2d_ASN1_INTEGER(ap, &tmp);
2545 i2d_ASN1_INTEGER(ag, &tmp);
2546 i2d_ASN1_INTEGER(aq, &tmp);
2547
2548 *buf_len = r;
2549
2550 retval = 0;
2551
2552 cleanup:
2553 if (ap != NULL)
2554 ASN1_INTEGER_free(ap);
2555 if (ag != NULL)
2556 ASN1_INTEGER_free(ag);
2557 if (aq != NULL)
2558 ASN1_INTEGER_free(aq);
2559
2560 return retval;
2561 }
2562
2563 static DH *
2564 pkinit_decode_dh_params(DH ** a, unsigned char **pp, unsigned int len)
2565 {
2566 ASN1_INTEGER ai, *aip = NULL;
2567 long length = (long) len;
2568
2569 M_ASN1_D2I_vars(a, DH *, DH_new);
2570
2571 M_ASN1_D2I_Init();
2572 M_ASN1_D2I_start_sequence();
2573 aip = &ai;
2574 ai.data = NULL;
2575 ai.length = 0;
2576 M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
2577 if (aip == NULL)
2578 return NULL;
2579 else {
2580 (*a)->p = ASN1_INTEGER_to_BN(aip, NULL);
2581 if ((*a)->p == NULL)
2582 return NULL;
2602 }
2603 M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
2604 if (aip == NULL)
2605 return NULL;
2606 else {
2607 (*a)->q = ASN1_INTEGER_to_BN(aip, NULL);
2608 if ((*a)->q == NULL)
2609 return NULL;
2610 if (ai.data != NULL) {
2611 OPENSSL_free(ai.data);
2612 ai.data = NULL;
2613 ai.length = 0;
2614 }
2615
2616 }
2617 M_ASN1_D2I_end_sequence();
2618 M_ASN1_D2I_Finish(a, DH_free, 0);
2619
2620 }
2621
2622 static krb5_error_code
2623 pkinit_create_sequence_of_principal_identifiers(
2624 krb5_context context,
2625 pkinit_plg_crypto_context plg_cryptoctx,
2626 pkinit_req_crypto_context req_cryptoctx,
2627 pkinit_identity_crypto_context id_cryptoctx,
2628 int type,
2629 krb5_data **out_data)
2630 {
2631 krb5_error_code retval = KRB5KRB_ERR_GENERIC;
2632 krb5_external_principal_identifier **krb5_trusted_certifiers = NULL;
2633 krb5_data *td_certifiers = NULL, *data = NULL;
2634 krb5_typed_data **typed_data = NULL;
2635
2636 switch(type) {
2637 case TD_TRUSTED_CERTIFIERS:
2638 retval = create_krb5_trustedCertifiers(context, plg_cryptoctx,
2639 req_cryptoctx, id_cryptoctx, &krb5_trusted_certifiers);
2640 if (retval) {
2641 pkiDebug("create_krb5_trustedCertifiers failed\n");
2746
2747 return retval;
2748 }
2749
2750 /* ARGSUSED */
2751 krb5_error_code
2752 pkinit_create_td_dh_parameters(krb5_context context,
2753 pkinit_plg_crypto_context plg_cryptoctx,
2754 pkinit_req_crypto_context req_cryptoctx,
2755 pkinit_identity_crypto_context id_cryptoctx,
2756 pkinit_plg_opts *opts,
2757 krb5_data **out_data)
2758 {
2759 /* Solaris Kerberos */
2760 krb5_error_code retval = KRB5KRB_ERR_GENERIC;
2761 unsigned int buf1_len = 0, buf2_len = 0, buf3_len = 0, i = 0;
2762 unsigned char *buf1 = NULL, *buf2 = NULL, *buf3 = NULL;
2763 krb5_typed_data **typed_data = NULL;
2764 krb5_data *data = NULL, *encoded_algId = NULL;
2765 krb5_algorithm_identifier **algId = NULL;
2766
2767 /* Solaris Kerberos */
2768 if (opts->dh_min_bits > 4096) {
2769 retval = EINVAL;
2770 goto cleanup;
2771 }
2772
2773 if (opts->dh_min_bits <= 1024) {
2774 retval = pkinit_encode_dh_params(plg_cryptoctx->dh_1024->p,
2775 plg_cryptoctx->dh_1024->g, plg_cryptoctx->dh_1024->q,
2776 &buf1, &buf1_len);
2777 if (retval)
2778 goto cleanup;
2779 }
2780 if (opts->dh_min_bits <= 2048) {
2781 retval = pkinit_encode_dh_params(plg_cryptoctx->dh_2048->p,
2782 plg_cryptoctx->dh_2048->g, plg_cryptoctx->dh_2048->q,
2783 &buf2, &buf2_len);
2784 if (retval)
2785 goto cleanup;
2786 }
2787 retval = pkinit_encode_dh_params(plg_cryptoctx->dh_4096->p,
2788 plg_cryptoctx->dh_4096->g, plg_cryptoctx->dh_4096->q,
2789 &buf3, &buf3_len);
2790 if (retval)
2791 goto cleanup;
2792
2793 if (opts->dh_min_bits <= 1024) {
2794 algId = malloc(4 * sizeof(krb5_algorithm_identifier *));
2795 if (algId == NULL)
2796 goto cleanup;
2797 algId[3] = NULL;
2798 algId[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
2799 if (algId[0] == NULL)
2800 goto cleanup;
2801 algId[0]->parameters.data = (unsigned char *)malloc(buf2_len);
2802 if (algId[0]->parameters.data == NULL)
2803 goto cleanup;
2804 (void) memcpy(algId[0]->parameters.data, buf2, buf2_len);
2805 algId[0]->parameters.length = buf2_len;
2806 algId[0]->algorithm = dh_oid;
2807
2808 algId[1] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
2809 if (algId[1] == NULL)
2963 if (is == NULL)
2964 goto cleanup;
2965
2966 status = X509_NAME_cmp(X509_get_issuer_name(kdc_cert), is->issuer);
2967 if (!status) {
2968 status = ASN1_INTEGER_cmp(X509_get_serialNumber(kdc_cert), is->serial);
2969 if (!status)
2970 *valid_kdcPkId = 1;
2971 }
2972
2973 retval = 0;
2974 cleanup:
2975 X509_NAME_free(is->issuer);
2976 ASN1_INTEGER_free(is->serial);
2977 free(is);
2978
2979 return retval;
2980 }
2981
2982 static int
2983 pkinit_check_dh_params(BIGNUM * p1, BIGNUM * p2, BIGNUM * g1, BIGNUM * q1)
2984 {
2985 BIGNUM *g2 = NULL, *q2 = NULL;
2986 /* Solaris Kerberos */
2987 int retval = EINVAL;
2988
2989 if (!BN_cmp(p1, p2)) {
2990 g2 = BN_new();
2991 BN_set_word(g2, DH_GENERATOR_2);
2992 if (!BN_cmp(g1, g2)) {
2993 q2 = BN_new();
2994 BN_rshift1(q2, p1);
2995 if (!BN_cmp(q1, q2)) {
2996 pkiDebug("good %d dhparams\n", BN_num_bits(p1));
2997 retval = 0;
2998 } else
2999 pkiDebug("bad group 2 q dhparameter\n");
3000 BN_free(q2);
3001 } else
3002 pkiDebug("bad g dhparameter\n");
3003 BN_free(g2);
3007 return retval;
3008 }
3009
3010 /* ARGSUSED */
3011 krb5_error_code
3012 pkinit_process_td_dh_params(krb5_context context,
3013 pkinit_plg_crypto_context cryptoctx,
3014 pkinit_req_crypto_context req_cryptoctx,
3015 pkinit_identity_crypto_context id_cryptoctx,
3016 krb5_algorithm_identifier **algId,
3017 int *new_dh_size)
3018 {
3019 krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
3020 int i = 0, use_sent_dh = 0, ok = 0;
3021
3022 pkiDebug("dh parameters\n");
3023
3024 while (algId[i] != NULL) {
3025 DH *dh = NULL;
3026 unsigned char *tmp = NULL;
3027 int dh_prime_bits = 0;
3028
3029 if (algId[i]->algorithm.length != dh_oid.length ||
3030 memcmp(algId[i]->algorithm.data, dh_oid.data, dh_oid.length))
3031 goto cleanup;
3032
3033 tmp = algId[i]->parameters.data;
3034 dh = DH_new();
3035 dh = pkinit_decode_dh_params(&dh, &tmp, algId[i]->parameters.length);
3036 dh_prime_bits = BN_num_bits(dh->p);
3037 pkiDebug("client sent %d DH bits server prefers %d DH bits\n",
3038 *new_dh_size, dh_prime_bits);
3039 switch(dh_prime_bits) {
3040 case 1024:
3041 if (pkinit_check_dh_params(cryptoctx->dh_1024->p, dh->p,
3042 dh->g, dh->q) == 0) {
3043 *new_dh_size = 1024;
3044 ok = 1;
3045 }
3046 break;
3047 case 2048:
3048 if (pkinit_check_dh_params(cryptoctx->dh_2048->p, dh->p,
3049 dh->g, dh->q) == 0) {
3050 *new_dh_size = 2048;
3051 ok = 1;
3052 }
3053 break;
3054 case 4096:
3055 if (pkinit_check_dh_params(cryptoctx->dh_4096->p, dh->p,
3056 dh->g, dh->q) == 0) {
3057 *new_dh_size = 4096;
3058 ok = 1;
3059 }
3060 break;
3061 default:
3062 break;
3063 }
3064 if (!ok) {
3065 DH_check(dh, &retval);
3066 if (retval != 0) {
3067 pkiDebug("DH parameters provided by server are unacceptable\n");
3068 retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
3069 }
3070 else {
3071 use_sent_dh = 1;
3072 ok = 1;
3073 }
3074 }
3075 if (!use_sent_dh)
3076 DH_free(dh);
3096 /* ARGSUSED */
3097 static int
3098 openssl_callback(int ok, X509_STORE_CTX * ctx)
3099 {
3100 #ifdef DEBUG
3101 if (!ok) {
3102 char buf[DN_BUF_LEN];
3103
3104 X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), buf, sizeof(buf));
3105 pkiDebug("cert = %s\n", buf);
3106 pkiDebug("callback function: %d (%s)\n", ctx->error,
3107 X509_verify_cert_error_string(ctx->error));
3108 }
3109 #endif
3110 return ok;
3111 }
3112
3113 static int
3114 openssl_callback_ignore_crls(int ok, X509_STORE_CTX * ctx)
3115 {
3116 if (!ok) {
3117 switch (ctx->error) {
3118 case X509_V_ERR_UNABLE_TO_GET_CRL:
3119 return 1;
3120 default:
3121 return 0;
3122 }
3123 }
3124 return ok;
3125 }
3126
3127 static ASN1_OBJECT *
3128 pkinit_pkcs7type2oid(pkinit_plg_crypto_context cryptoctx, int pkcs7_type)
3129 {
3130 int nid;
3131
3132 switch (pkcs7_type) {
3133 case CMS_SIGN_CLIENT:
3134 return cryptoctx->id_pkinit_authData;
3135 case CMS_SIGN_DRAFT9:
3136 /*
3137 * Delay creating this OID until we know we need it.
3138 * It shadows an existing OpenSSL oid. If it
3139 * is created too early, it breaks things like
3140 * the use of pkcs12 (which uses pkcs7 structures).
3141 * We need this shadow version because our code
3142 * depends on the "other" type to be unknown to the
3143 * OpenSSL code.
3292 ASN1_put_object(&p, 1, (int)(orig_len+oid_len),
3293 V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
3294
3295 i2d_ASN1_OBJECT(oid, &p);
3296
3297 ASN1_put_object(&p, 1, (int)data_len, 0, V_ASN1_CONTEXT_SPECIFIC);
3298 (void) memcpy(p, data, data_len);
3299
3300 *out_len = tot_len;
3301
3302 return 0;
3303 }
3304 #endif
3305
3306 static int
3307 prepare_enc_data(unsigned char *indata,
3308 int indata_len,
3309 unsigned char **outdata,
3310 int *outdata_len)
3311 {
3312 /* Solaris Kerberos */
3313 ASN1_const_CTX c;
3314 long length = indata_len;
3315 int Ttag, Tclass;
3316 long Tlen;
3317
3318 c.pp = (const unsigned char **)&indata;
3319 c.q = *(const unsigned char **)&indata;
3320 c.error = ERR_R_NESTED_ASN1_ERROR;
3321 c.p= *(const unsigned char **)&indata;
3322 c.max = (length == 0)?0:(c.p+length);
3323
3324 asn1_GetSequence(&c,&length);
3325
3326 ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen);
3327 c.p += Tlen;
3328 ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen);
3329
3330 asn1_const_Finish(&c);
3331
3332 *outdata = (unsigned char *)malloc((size_t)Tlen);
3333 /* Solaris Kerberos */
3334 if (outdata == NULL)
3335 return ENOMEM;
3336
3337 (void) memcpy(*outdata, c.p, (size_t)Tlen);
3338 *outdata_len = Tlen;
3339
3340 return 0;
3341 }
3342
3343 #ifndef WITHOUT_PKCS11
3344 static void *
3345 pkinit_C_LoadModule(const char *modname, CK_FUNCTION_LIST_PTR_PTR p11p)
3346 {
3347 void *handle;
3348 CK_RV (*getflist)(CK_FUNCTION_LIST_PTR_PTR);
3349
3350 pkiDebug("loading module \"%s\"... ", modname);
3351 /* Solaris Kerberos */
3352 handle = dlopen(modname, RTLD_NOW | RTLD_GROUP);
3353 if (handle == NULL) {
3354 pkiDebug("not found\n");
3355 return NULL;
3356 }
3357 getflist = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR)) dlsym(handle, "C_GetFunctionList");
3358 if (getflist == NULL || (*getflist)(p11p) != CKR_OK) {
3359 (void) dlclose(handle);
4351 * You must call pkinit_get_certs before calling pkinit_find_private_key
4352 * (that's because we need the ID of the private key)
4353 *
4354 * pkcs11 says the id of the key doesn't have to match that of the cert, but
4355 * I can't figure out any other way to decide which key to use.
4356 *
4357 * We should only find one key that fits all the requirements.
4358 * If there are more than one, we just take the first one.
4359 */
4360
4361 /* ARGSUSED */
4362 krb5_error_code
4363 pkinit_find_private_key(pkinit_identity_crypto_context id_cryptoctx,
4364 CK_ATTRIBUTE_TYPE usage,
4365 CK_OBJECT_HANDLE *objp)
4366 {
4367 CK_OBJECT_CLASS cls;
4368 CK_ATTRIBUTE attrs[4];
4369 CK_ULONG count;
4370 CK_KEY_TYPE keytype;
4371 unsigned int nattrs = 0;
4372 int r;
4373 #ifdef PKINIT_USE_KEY_USAGE
4374 CK_BBOOL true_false;
4375 #endif
4376
4377 cls = CKO_PRIVATE_KEY;
4378 attrs[nattrs].type = CKA_CLASS;
4379 attrs[nattrs].pValue = &cls;
4380 attrs[nattrs].ulValueLen = sizeof cls;
4381 nattrs++;
4382
4383 #ifdef PKINIT_USE_KEY_USAGE
4384 /*
4385 * Some cards get confused if you try to specify a key usage,
4386 * so don't, and hope for the best. This will fail if you have
4387 * several keys with the same id and different usages but I have
4388 * not seen this on real cards.
4389 */
4390 true_false = TRUE;
4411 pkinit_pkcs11_code_to_text(r));
4412 return KRB5KDC_ERR_PREAUTH_FAILED;
4413 }
4414
4415 r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1, &count);
4416 id_cryptoctx->p11->C_FindObjectsFinal(id_cryptoctx->session);
4417 pkiDebug("found %d private keys (%s)\n", (int) count, pkinit_pkcs11_code_to_text(r));
4418
4419 /*
4420 * Solaris Kerberos:
4421 * The CKA_ID may not be correctly set for the private key. For e.g. when
4422 * storing a private key in softtoken pktool(1) doesn't generate or store
4423 * a CKA_ID for the private key. Another way to identify the private key is
4424 * to look for a private key with the same RSA modulus as the public key
4425 * in the certificate.
4426 */
4427 if (r == CKR_OK && count != 1) {
4428
4429 EVP_PKEY *priv;
4430 X509 *cert;
4431 unsigned int n_len;
4432 unsigned char *n_bytes;
4433
4434 cert = sk_X509_value(id_cryptoctx->my_certs, 0);
4435 priv = X509_get_pubkey(cert);
4436 if (priv == NULL) {
4437 pkiDebug("Failed to extract pub key from cert\n");
4438 return KRB5KDC_ERR_PREAUTH_FAILED;
4439 }
4440
4441 nattrs = 0;
4442 cls = CKO_PRIVATE_KEY;
4443 attrs[nattrs].type = CKA_CLASS;
4444 attrs[nattrs].pValue = &cls;
4445 attrs[nattrs].ulValueLen = sizeof cls;
4446 nattrs++;
4447
4448 #ifdef PKINIT_USE_KEY_USAGE
4449 true_false = TRUE;
4450 attrs[nattrs].type = usage;
4451 attrs[nattrs].pValue = &true_false;
4452 attrs[nattrs].ulValueLen = sizeof true_false;
4453 nattrs++;
4454 #endif
4455
4456 keytype = CKK_RSA;
4457 attrs[nattrs].type = CKA_KEY_TYPE;
4458 attrs[nattrs].pValue = &keytype;
4459 attrs[nattrs].ulValueLen = sizeof keytype;
4460 nattrs++;
4461
4462 n_len = BN_num_bytes(priv->pkey.rsa->n);
4463 n_bytes = (unsigned char *) malloc((size_t) n_len);
4464 if (n_bytes == NULL) {
4465 return (ENOMEM);
4466 }
4467
4468 if (BN_bn2bin(priv->pkey.rsa->n, n_bytes) == 0) {
4469 free (n_bytes);
4470 pkiDebug("zero-byte key modulus\n");
4471 return KRB5KDC_ERR_PREAUTH_FAILED;
4472 }
4473
4474 attrs[nattrs].type = CKA_MODULUS;
4475 attrs[nattrs].ulValueLen = n_len;
4476 attrs[nattrs].pValue = n_bytes;
4477
4478 nattrs++;
4479
4480 r = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs, nattrs);
4481 free (n_bytes);
4482 if (r != CKR_OK) {
4483 pkiDebug("krb5_pkinit_sign_data: C_FindObjectsInit: %s\n",
4484 pkinit_pkcs11_code_to_text(r));
4485 return KRB5KDC_ERR_PREAUTH_FAILED;
4486 }
4487
4488 r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1, &count);
4757 /* Solaris Kerberos */
4758 int len;
4759 unsigned char *buf = NULL;
4760 int buf_len = 0;
4761
4762 /* Solaris Kerberos */
4763 if (out_data == NULL || out_data_len == NULL)
4764 return EINVAL;
4765
4766 if (cert && !X509_check_private_key(cert, pkey)) {
4767 pkiDebug("private key does not match certificate\n");
4768 /* Solaris Kerberos */
4769 return EINVAL;
4770 }
4771
4772 buf_len = EVP_PKEY_size(pkey);
4773 buf = (unsigned char *)malloc((size_t) buf_len + 10);
4774 if (buf == NULL)
4775 return ENOMEM;
4776
4777 #if OPENSSL_VERSION_NUMBER < 0x10000000L
4778 len = EVP_PKEY_decrypt(buf, data, (int)data_len, pkey);
4779 #else
4780 len = EVP_PKEY_decrypt_old(buf, data, (int)data_len, pkey);
4781 #endif
4782 if (len <= 0) {
4783 pkiDebug("unable to decrypt received data (len=%d)\n", data_len);
4784 /* Solaris Kerberos */
4785 free(buf);
4786 return KRB5KRB_ERR_GENERIC;
4787 }
4788 *out_data = buf;
4789 *out_data_len = len;
4790
4791 return 0;
4792 }
4793
4794 static krb5_error_code
4795 create_signature(unsigned char **sig, unsigned int *sig_len,
4796 unsigned char *data, unsigned int data_len, EVP_PKEY *pkey)
4797 {
4798 krb5_error_code retval = ENOMEM;
4799 EVP_MD_CTX md_ctx;
4800
4801 if (pkey == NULL)
4802 /* Solaris Kerberos */
4803 return EINVAL;
4804
4805 EVP_VerifyInit(&md_ctx, EVP_sha1());
4806 EVP_SignUpdate(&md_ctx, data, data_len);
4807 *sig_len = EVP_PKEY_size(pkey);
4808 if ((*sig = (unsigned char *) malloc((size_t) *sig_len)) == NULL)
4809 goto cleanup;
4810 EVP_SignFinal(&md_ctx, *sig, sig_len, pkey);
4811
4812 retval = 0;
4813
4814 cleanup:
4815 EVP_MD_CTX_cleanup(&md_ctx);
4816
4817 return retval;
4818 }
4819
4820 /*
4821 * Note:
4822 * This is not the routine the KDC uses to get its certificate.
4823 * This routine is intended to be called by the client
4824 * to obtain the KDC's certificate from some local storage
4825 * to be sent as a hint in its request to the KDC.
4826 */
4827 /* ARGSUSED */
4828 krb5_error_code
4829 pkinit_get_kdc_cert(krb5_context context,
4830 pkinit_plg_crypto_context plg_cryptoctx,
4831 pkinit_req_crypto_context req_cryptoctx,
4832 pkinit_identity_crypto_context id_cryptoctx,
4833 krb5_principal princ)
4834 {
4835 /* Solaris Kerberos */
6081 krb5_cas[i]->subjectName.length = 0;
6082 krb5_cas[i]->subjectName.data = NULL;
6083
6084 xn = X509_get_subject_name(x);
6085 len = i2d_X509_NAME(xn, NULL);
6086 if ((p = krb5_cas[i]->subjectName.data = (unsigned char *)malloc((size_t) len)) == NULL)
6087 goto cleanup;
6088 i2d_X509_NAME(xn, &p);
6089 krb5_cas[i]->subjectName.length = len;
6090
6091 /* fill-in issuerAndSerialNumber */
6092 krb5_cas[i]->issuerAndSerialNumber.length = 0;
6093 krb5_cas[i]->issuerAndSerialNumber.magic = 0;
6094 krb5_cas[i]->issuerAndSerialNumber.data = NULL;
6095
6096 #ifdef LONGHORN_BETA_COMPAT
6097 if (longhorn == 0) { /* XXX Longhorn doesn't like this */
6098 #endif
6099 is = PKCS7_ISSUER_AND_SERIAL_new();
6100 X509_NAME_set(&is->issuer, X509_get_issuer_name(x));
6101 M_ASN1_INTEGER_free(is->serial);
6102 is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(x));
6103 len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
6104 if ((p = krb5_cas[i]->issuerAndSerialNumber.data =
6105 (unsigned char *)malloc((size_t) len)) == NULL)
6106 goto cleanup;
6107 i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
6108 krb5_cas[i]->issuerAndSerialNumber.length = len;
6109 #ifdef LONGHORN_BETA_COMPAT
6110 }
6111 #endif
6112
6113 /* fill-in subjectKeyIdentifier */
6114 krb5_cas[i]->subjectKeyIdentifier.length = 0;
6115 krb5_cas[i]->subjectKeyIdentifier.magic = 0;
6116 krb5_cas[i]->subjectKeyIdentifier.data = NULL;
6117
6118
6119 #ifdef LONGHORN_BETA_COMPAT
6120 if (longhorn == 0) { /* XXX Longhorn doesn't like this */
6121 #endif
6122 if (X509_get_ext_by_NID(x, NID_subject_key_identifier, -1) >= 0) {
6286 krb5_cas[i]->choice = choice_trusted_cas_principalName;
6287 break;
6288 case choice_trusted_cas_caName:
6289 krb5_cas[i]->choice = choice_trusted_cas_caName;
6290 krb5_cas[i]->u.caName.data = NULL;
6291 krb5_cas[i]->u.caName.length = 0;
6292 xn = X509_get_subject_name(x);
6293 len = i2d_X509_NAME(xn, NULL);
6294 if ((p = krb5_cas[i]->u.caName.data =
6295 (unsigned char *)malloc((size_t) len)) == NULL)
6296 goto cleanup;
6297 i2d_X509_NAME(xn, &p);
6298 krb5_cas[i]->u.caName.length = len;
6299 break;
6300 case choice_trusted_cas_issuerAndSerial:
6301 krb5_cas[i]->choice = choice_trusted_cas_issuerAndSerial;
6302 krb5_cas[i]->u.issuerAndSerial.data = NULL;
6303 krb5_cas[i]->u.issuerAndSerial.length = 0;
6304 is = PKCS7_ISSUER_AND_SERIAL_new();
6305 X509_NAME_set(&is->issuer, X509_get_issuer_name(x));
6306 M_ASN1_INTEGER_free(is->serial);
6307 is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(x));
6308 len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
6309 if ((p = krb5_cas[i]->u.issuerAndSerial.data =
6310 (unsigned char *)malloc((size_t) len)) == NULL)
6311 goto cleanup;
6312 i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
6313 krb5_cas[i]->u.issuerAndSerial.length = len;
6314 if (is != NULL) {
6315 if (is->issuer != NULL)
6316 X509_NAME_free(is->issuer);
6317 if (is->serial != NULL)
6318 ASN1_INTEGER_free(is->serial);
6319 free(is);
6320 }
6321 break;
6322 default: break;
6323 }
6324 }
6325 retval = 0;
6326 *ids = krb5_cas;
6327 cleanup:
6336 create_issuerAndSerial(krb5_context context,
6337 pkinit_plg_crypto_context plg_cryptoctx,
6338 pkinit_req_crypto_context req_cryptoctx,
6339 pkinit_identity_crypto_context id_cryptoctx,
6340 unsigned char **out,
6341 unsigned int *out_len)
6342 {
6343 unsigned char *p = NULL;
6344 PKCS7_ISSUER_AND_SERIAL *is = NULL;
6345 int len = 0;
6346 krb5_error_code retval = ENOMEM;
6347 X509 *cert = req_cryptoctx->received_cert;
6348
6349 *out = NULL;
6350 *out_len = 0;
6351 if (req_cryptoctx->received_cert == NULL)
6352 return 0;
6353
6354 is = PKCS7_ISSUER_AND_SERIAL_new();
6355 X509_NAME_set(&is->issuer, X509_get_issuer_name(cert));
6356 M_ASN1_INTEGER_free(is->serial);
6357 is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert));
6358 len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
6359 if ((p = *out = (unsigned char *)malloc((size_t) len)) == NULL)
6360 goto cleanup;
6361 i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
6362 *out_len = len;
6363 retval = 0;
6364
6365 cleanup:
6366 X509_NAME_free(is->issuer);
6367 ASN1_INTEGER_free(is->serial);
6368 free(is);
6369
6370 return retval;
6371 }
6372
6373 static int
6374 pkcs7_decrypt(krb5_context context,
6375 pkinit_identity_crypto_context id_cryptoctx,
6376 PKCS7 *p7,
6377 BIO *data)
6522 xalg=p7->d.enveloped->enc_data->algorithm;
6523 #endif
6524
6525 if ((etmp=BIO_new(BIO_f_cipher())) == NULL) {
6526 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
6527 goto cleanup;
6528 }
6529
6530 /* It was encrypted, we need to decrypt the secret key
6531 * with the private key */
6532
6533 /* Find the recipientInfo which matches the passed certificate
6534 * (if any)
6535 */
6536
6537 if (cert) {
6538 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
6539 int tmp_ret = 0;
6540 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
6541 tmp_ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
6542 cert->cert_info->issuer);
6543 if (!tmp_ret) {
6544 tmp_ret = M_ASN1_INTEGER_cmp(cert->cert_info->serialNumber,
6545 ri->issuer_and_serial->serial);
6546 if (!tmp_ret)
6547 break;
6548 }
6549 ri=NULL;
6550 }
6551 if (ri == NULL) {
6552 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
6553 PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
6554 goto cleanup;
6555 }
6556
6557 }
6558
6559 /* If we haven't got a certificate try each ri in turn */
6560
6561 if (cert == NULL) {
6562 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
6563 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
6564 jj = pkinit_decode_data(context, id_cryptoctx,
6565 M_ASN1_STRING_data(ri->enc_key),
6566 (unsigned int) M_ASN1_STRING_length(ri->enc_key),
6567 &tmp, &tmp_len);
6568 if (jj) {
6569 PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB);
6570 goto cleanup;
6571 }
6572
6573 if (!jj && tmp_len > 0) {
6574 jj = tmp_len;
6575 break;
6576 }
6577
6578 ERR_clear_error();
6579 ri = NULL;
6580 }
6581
6582 if (ri == NULL) {
6583 PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_RECIPIENT_MATCHES_KEY);
6584 goto cleanup;
6585 }
6586 }
6587 else {
6588 jj = pkinit_decode_data(context, id_cryptoctx,
6589 M_ASN1_STRING_data(ri->enc_key),
6590 (unsigned int) M_ASN1_STRING_length(ri->enc_key),
6591 &tmp, &tmp_len);
6592 /* Solaris Kerberos: tmp_len is unsigned. Cannot be < 0 */
6593 if (jj || tmp_len == 0) {
6594 PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB);
6595 goto cleanup;
6596 }
6597 jj = tmp_len;
6598 }
6599
6600 evp_ctx=NULL;
6601 BIO_get_cipher_ctx(etmp,&evp_ctx);
6602 if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0)
6603 goto cleanup;
6604 if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
6605 goto cleanup;
6606
6607 if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) {
6608 /* Some S/MIME clients don't use the same key
6609 * and effective key length. The key length is
6610 * determined by the size of the decrypted RSA key.
6611 */
6612 if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, (int)jj)) {
6613 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
6614 PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
6615 goto cleanup;
6616 }
6617 }
6618 if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0)
6619 goto cleanup;
6620
6621 OPENSSL_cleanse(tmp,jj);
6622
6623 if (out == NULL)
6624 out=etmp;
6625 else
6626 BIO_push(out,etmp);
6627 etmp=NULL;
6628
6629 if (data_body->length > 0)
6630 bio = BIO_new_mem_buf(data_body->data, data_body->length);
6631 else {
6632 bio=BIO_new(BIO_s_mem());
6633 BIO_set_mem_eof_return(bio,0);
6634 }
|
14 * portion of this software, then the disclaimer below must
15 * also be included.
16 *
17 * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
18 * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
19 * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
20 * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
21 * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
23 * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
24 * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
25 * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
26 * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
27 * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGES.
29 */
30
31 /*
32 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
33 * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved.
34 * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
35 */
36
37 #include <errno.h>
38 #include <string.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <dlfcn.h>
42 #include <unistd.h>
43 #include <dirent.h>
44
45
46 /* Solaris Kerberos */
47 #include <libintl.h>
48 #include <assert.h>
49 #include <security/pam_appl.h>
50 #include <ctype.h>
51 #include "k5-int.h"
52 #include <ctype.h>
53
54 /*
353 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
354 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
355 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
356 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
357 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
358 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
359 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
360 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
361 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
362 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
363 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
364 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
365 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
366 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
367 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
368 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
369 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
370 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
371 };
372
373 #if OPENSSL_VERSION_NUMBER < 0x10100000L
374 /*
375 * Many things have changed in OpenSSL 1.1. The code in this file has been
376 * updated to use the v1.1 APIs but some are new and require emulation
377 * for older OpenSSL versions.
378 */
379
380 /* EVP_MD_CTX construct and destructor names have changed */
381
382 #define EVP_MD_CTX_new EVP_MD_CTX_create
383 #define EVP_MD_CTX_free EVP_MD_CTX_destroy
384
385 /* ASN1_STRING_data is deprecated */
386 #define ASN1_STRING_get0_data ASN1_STRING_data
387
388 /* X509_STORE_CTX_trusted_stack is deprecated */
389 #define X509_STORE_CTX_set0_trusted_stack X509_STORE_CTX_trusted_stack
390
391 /* get_rfc2409_prime_1024() has been renamed. */
392 #define BN_get_rfc2409_prime_1024 get_rfc2409_prime_1024
393
394 #define OBJ_get0_data(o) ((o)->data)
395 #define OBJ_length(o) ((o)->length)
396
397 /* Some new DH functions that aren't in OpenSSL 1.0.x */
398 #define DH_bits(dh) BN_num_bits((dh)->p);
399
400 #define DH_set0_pqg(dh, p, q, g) __DH_set0_pqg(dh, p, q, g)
401 static int
402 __DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
403 {
404 if ((dh->p == NULL && p == NULL) || (dh->g == NULL && g == NULL))
405 return 0;
406
407 if (p != NULL) {
408 BN_free(dh->p);
409 dh->p = p;
410 }
411 if (q != NULL) {
412 BN_free(dh->q);
413 dh->q = q;
414 }
415 if (g != NULL) {
416 BN_free(dh->g);
417 dh->g = g;
418 }
419
420 if (q != NULL) {
421 dh->length = BN_num_bits(q);
422 }
423
424 return 1;
425 }
426
427 #define DH_get0_pqg(dh, p, q, g) __DH_get0_pqg(dh, p, q, g)
428 static void
429 __DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q,
430 const BIGNUM **g)
431 {
432 if (p != NULL)
433 *p = dh->p;
434 if (q != NULL)
435 *q = dh->q;
436 if (g != NULL)
437 *g = dh->g;
438 }
439
440 #define DH_set0_key(dh, pub, priv) __DH_set0_key(dh, pub, priv)
441 static int
442 __DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
443 {
444 if (pub_key != NULL) {
445 BN_free(dh->pub_key);
446 dh->pub_key = pub_key;
447 }
448 if (priv_key != NULL) {
449 BN_free(dh->priv_key);
450 dh->priv_key = priv_key;
451 }
452
453 return 1;
454 }
455
456 #define DH_get0_key(dh, pub, priv) __DH_get0_key(dh, pub, priv)
457 static void
458 __DH_get0_key(const DH *dh, const BIGNUM **pub, const BIGNUM **priv)
459 {
460 if (pub != NULL)
461 *pub = dh->pub_key;
462 if (priv != NULL)
463 *priv = dh->priv_key;
464 }
465
466 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
467
468 /* Solaris Kerberos */
469 static k5_mutex_t oids_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
470 static int pkinit_oids_refs = 0;
471
472 krb5_error_code
473 pkinit_init_plg_crypto(pkinit_plg_crypto_context *cryptoctx) {
474
475 krb5_error_code retval = ENOMEM;
476 pkinit_plg_crypto_context ctx = NULL;
477
478 /* initialize openssl routines */
479 /* Solaris Kerberos */
480 retval = openssl_init();
481 if (retval != 0)
482 goto out;
483
484 ctx = (pkinit_plg_crypto_context)malloc(sizeof(*ctx));
485 if (ctx == NULL)
486 goto out;
487 (void) memset(ctx, 0, sizeof(*ctx));
735 pkiDebug("failed to read private key from %s\n", filename);
736 goto cleanup;
737 }
738 *retkey = pkey;
739 retval = 0;
740 cleanup:
741 if (tmp != NULL)
742 BIO_free(tmp);
743 return retval;
744 }
745
746 static void
747 pkinit_fini_pkinit_oids(pkinit_plg_crypto_context ctx)
748 {
749 if (ctx == NULL)
750 return;
751
752 /* Only call OBJ_cleanup once! */
753 /* Solaris Kerberos: locking */
754 k5_mutex_lock(&oids_mutex);
755 #if OPENSSL_VERSION_NUMBER < 0x10100000L
756 /*
757 * In OpenSSL versions prior to 1.1.0, OBJ_cleanup() cleaned up OpenSSL's
758 * internal object table. This function is deprecated in version 1.1.0.
759 * No explicit de-initialisation is now required.
760 */
761 if (--pkinit_oids_refs == 0)
762 OBJ_cleanup();
763 #else
764 pkinit_oids_refs--;
765 #endif
766 k5_mutex_unlock(&oids_mutex);
767 }
768
769 /* Construct an OpenSSL DH object for an Oakley group. */
770 static DH *
771 make_dhprime(uint8_t *prime, size_t len)
772 {
773 DH *dh = NULL;
774 BIGNUM *p = NULL, *q = NULL, *g = NULL;
775
776 if ((p = BN_bin2bn(prime, len, NULL)) == NULL)
777 goto cleanup;
778 if ((q = BN_new()) == NULL)
779 goto cleanup;
780 if (!BN_rshift1(q, p))
781 goto cleanup;
782 if ((g = BN_new()) == NULL)
783 goto cleanup;
784 if (!BN_set_word(g, DH_GENERATOR_2))
785 goto cleanup;
786
787 dh = DH_new();
788 if (dh == NULL)
789 goto cleanup;
790 DH_set0_pqg(dh, p, q, g);
791 p = g = q = NULL;
792
793 cleanup:
794 BN_free(p);
795 BN_free(q);
796 BN_free(g);
797 return dh;
798 }
799
800 static krb5_error_code
801 pkinit_init_dh_params(pkinit_plg_crypto_context plgctx)
802 {
803 krb5_error_code retval = ENOMEM;
804
805 plgctx->dh_1024 = make_dhprime(pkinit_1024_dhprime,
806 sizeof(pkinit_1024_dhprime));
807 if (plgctx->dh_1024 == NULL)
808 goto cleanup;
809
810 plgctx->dh_2048 = make_dhprime(pkinit_2048_dhprime,
811 sizeof(pkinit_2048_dhprime));
812 if (plgctx->dh_2048 == NULL)
813 goto cleanup;
814
815 plgctx->dh_4096 = make_dhprime(pkinit_4096_dhprime,
816 sizeof(pkinit_4096_dhprime));
817 if (plgctx->dh_4096 == NULL)
818 goto cleanup;
819
820 retval = 0;
821
822 cleanup:
823 if (retval)
824 pkinit_fini_dh_params(plgctx);
825
826 return retval;
827 }
828
829 static void
830 pkinit_fini_dh_params(pkinit_plg_crypto_context plgctx)
831 {
832 if (plgctx->dh_1024 != NULL)
833 DH_free(plgctx->dh_1024);
834 if (plgctx->dh_2048 != NULL)
835 DH_free(plgctx->dh_2048);
836 if (plgctx->dh_4096 != NULL)
837 DH_free(plgctx->dh_4096);
838
959 cms_signeddata_create(krb5_context context,
960 pkinit_plg_crypto_context plg_cryptoctx,
961 pkinit_req_crypto_context req_cryptoctx,
962 pkinit_identity_crypto_context id_cryptoctx,
963 int cms_msg_type,
964 int include_certchain,
965 unsigned char *data,
966 unsigned int data_len,
967 unsigned char **signed_data,
968 unsigned int *signed_data_len)
969 {
970 /* Solaris Kerberos */
971 krb5_error_code retval = KRB5KRB_ERR_GENERIC;
972 PKCS7 *p7 = NULL, *inner_p7 = NULL;
973 PKCS7_SIGNED *p7s = NULL;
974 PKCS7_SIGNER_INFO *p7si = NULL;
975 unsigned char *p;
976 ASN1_TYPE *pkinit_data = NULL;
977 STACK_OF(X509) * cert_stack = NULL;
978 ASN1_OCTET_STRING *digest_attr = NULL;
979 EVP_MD_CTX *ctx = NULL, *ctx2 = NULL;
980 const EVP_MD *md_tmp = NULL;
981 unsigned char md_data[EVP_MAX_MD_SIZE], md_data2[EVP_MAX_MD_SIZE];
982 unsigned char *digestInfo_buf = NULL, *abuf = NULL;
983 unsigned int md_len, md_len2, alen, digestInfo_len;
984 STACK_OF(X509_ATTRIBUTE) * sk;
985 unsigned char *sig = NULL;
986 unsigned int sig_len = 0;
987 X509_ALGOR *alg = NULL;
988 ASN1_OCTET_STRING *digest = NULL;
989 unsigned int alg_len = 0, digest_len = 0;
990 unsigned char *y = NULL, *alg_buf = NULL, *digest_buf = NULL;
991 X509 *cert = NULL;
992 ASN1_OBJECT *oid = NULL;
993
994 /* Solaris Kerberos */
995 if (signed_data == NULL)
996 return EINVAL;
997
998 if (signed_data_len == NULL)
999 return EINVAL;
1003 goto cleanup;
1004 p7->type = OBJ_nid2obj(NID_pkcs7_signed);
1005
1006 if ((p7s = PKCS7_SIGNED_new()) == NULL)
1007 goto cleanup;
1008 p7->d.sign = p7s;
1009 if (!ASN1_INTEGER_set(p7s->version, 3))
1010 goto cleanup;
1011
1012 /* create a cert chain that has at least the signer's certificate */
1013 if ((cert_stack = sk_X509_new_null()) == NULL)
1014 goto cleanup;
1015
1016 cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index);
1017 if (!include_certchain) {
1018 pkiDebug("only including signer's certificate\n");
1019 sk_X509_push(cert_stack, X509_dup(cert));
1020 } else {
1021 /* create a cert chain */
1022 X509_STORE *certstore = NULL;
1023 X509_STORE_CTX *certctx;
1024 STACK_OF(X509) *certstack = NULL;
1025 char buf[DN_BUF_LEN];
1026 int i = 0, size = 0;
1027
1028 if ((certstore = X509_STORE_new()) == NULL)
1029 goto cleanup;
1030 if ((certctx = X509_STORE_CTX_new()) == NULL)
1031 goto cleanup;
1032 pkiDebug("building certificate chain\n");
1033 X509_STORE_set_verify_cb(certstore, openssl_callback);
1034 X509_STORE_CTX_init(certctx, certstore, cert,
1035 id_cryptoctx->intermediateCAs);
1036 X509_STORE_CTX_set0_trusted_stack(certctx, id_cryptoctx->trustedCAs);
1037 /* Solaris Kerberos */
1038 if (X509_verify_cert(certctx) <= 0) {
1039 pkiDebug("failed to create a certificate chain: %s\n",
1040 X509_verify_cert_error_string(X509_STORE_CTX_get_error(certctx)));
1041 if (!sk_X509_num(id_cryptoctx->trustedCAs))
1042 pkiDebug("No trusted CAs found. Check your X509_anchors\n");
1043 goto cleanup;
1044 }
1045 certstack = X509_STORE_CTX_get1_chain(certctx);
1046 size = sk_X509_num(certstack);
1047 pkiDebug("size of certificate chain = %d\n", size);
1048 for(i = 0; i < size - 1; i++) {
1049 X509 *x = sk_X509_value(certstack, i);
1050 X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf));
1051 pkiDebug("cert #%d: %s\n", i, buf);
1052 sk_X509_push(cert_stack, X509_dup(x));
1053 }
1054 X509_STORE_CTX_free(certctx);
1055 X509_STORE_free(certstore);
1056 sk_X509_pop_free(certstack, X509_free);
1057 }
1058 p7s->cert = cert_stack;
1059
1060 /* fill-in PKCS7_SIGNER_INFO */
1061 if ((p7si = PKCS7_SIGNER_INFO_new()) == NULL)
1062 goto cleanup;
1063 if (!ASN1_INTEGER_set(p7si->version, 1))
1064 goto cleanup;
1065 if (!X509_NAME_set(&p7si->issuer_and_serial->issuer,
1066 X509_get_issuer_name(cert)))
1067 goto cleanup;
1068 /* because ASN1_INTEGER_set is used to set a 'long' we will do
1069 * things the ugly way. */
1070 ASN1_INTEGER_free(p7si->issuer_and_serial->serial);
1071 if (!(p7si->issuer_and_serial->serial =
1072 ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
1073 goto cleanup;
1074
1075 /* will not fill-out EVP_PKEY because it's on the smartcard */
1076
1077 /* Set digest algs */
1078 p7si->digest_alg->algorithm = OBJ_nid2obj(NID_sha1);
1079
1080 if (p7si->digest_alg->parameter != NULL)
1081 ASN1_TYPE_free(p7si->digest_alg->parameter);
1082 if ((p7si->digest_alg->parameter = ASN1_TYPE_new()) == NULL)
1083 goto cleanup;
1084 p7si->digest_alg->parameter->type = V_ASN1_NULL;
1085
1086 /* Set sig algs */
1087 if (p7si->digest_enc_alg->parameter != NULL)
1088 ASN1_TYPE_free(p7si->digest_enc_alg->parameter);
1089 p7si->digest_enc_alg->algorithm = OBJ_nid2obj(NID_sha1WithRSAEncryption);
1090 if (!(p7si->digest_enc_alg->parameter = ASN1_TYPE_new()))
1091 goto cleanup;
1092 p7si->digest_enc_alg->parameter->type = V_ASN1_NULL;
1093
1094 /* pick the correct oid for the eContentInfo */
1095 oid = pkinit_pkcs7type2oid(plg_cryptoctx, cms_msg_type);
1096 if (oid == NULL)
1097 goto cleanup;
1098
1099 if (cms_msg_type == CMS_SIGN_DRAFT9) {
1100 /* don't include signed attributes for pa-type 15 request */
1101 abuf = data;
1102 alen = data_len;
1103 } else {
1104 /* add signed attributes */
1105 /* compute sha1 digest over the EncapsulatedContentInfo */
1106 ctx = EVP_MD_CTX_new();
1107 if (ctx == NULL)
1108 goto cleanup2;
1109 EVP_MD_CTX_init(ctx);
1110 EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
1111 EVP_DigestUpdate(ctx, data, data_len);
1112 md_tmp = EVP_MD_CTX_md(ctx);
1113 EVP_DigestFinal_ex(ctx, md_data, &md_len);
1114 EVP_MD_CTX_free(ctx);
1115 ctx = NULL;
1116
1117 /* create a message digest attr */
1118 digest_attr = ASN1_OCTET_STRING_new();
1119 ASN1_OCTET_STRING_set(digest_attr, md_data, (int)md_len);
1120 PKCS7_add_signed_attribute(p7si, NID_pkcs9_messageDigest,
1121 V_ASN1_OCTET_STRING, (char *) digest_attr);
1122
1123 /* create a content-type attr */
1124 PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType,
1125 V_ASN1_OBJECT, oid);
1126
1127 /* create the signature over signed attributes. get DER encoded value */
1128 /* This is the place where smartcard signature needs to be calculated */
1129 sk = p7si->auth_attr;
1130 alen = ASN1_item_i2d((ASN1_VALUE *) sk, &abuf,
1131 ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
1132 if (abuf == NULL)
1133 goto cleanup2;
1134 }
1135
1136 #ifndef WITHOUT_PKCS11
1137 /* Some tokens can only do RSAEncryption without sha1 hash */
1138 /* to compute sha1WithRSAEncryption, encode the algorithm ID for the hash
1139 * function and the hash value into an ASN.1 value of type DigestInfo
1140 * DigestInfo::=SEQUENCE {
1141 * digestAlgorithm AlgorithmIdentifier,
1142 * digest OCTET STRING }
1143 */
1144 if (id_cryptoctx->pkcs11_method == 1 &&
1145 id_cryptoctx->mech == CKM_RSA_PKCS) {
1146 pkiDebug("mech = CKM_RSA_PKCS\n");
1147 ctx2 = EVP_MD_CTX_new();
1148 if (ctx2 == NULL)
1149 goto cleanup2;
1150 EVP_MD_CTX_init(ctx2);
1151 /* if this is not draft9 request, include digest signed attribute */
1152 if (cms_msg_type != CMS_SIGN_DRAFT9)
1153 EVP_DigestInit_ex(ctx2, md_tmp, NULL);
1154 else
1155 EVP_DigestInit_ex(ctx2, EVP_sha1(), NULL);
1156 EVP_DigestUpdate(ctx2, abuf, alen);
1157 EVP_DigestFinal_ex(ctx2, md_data2, &md_len2);
1158 EVP_MD_CTX_free(ctx2);
1159 ctx2 = NULL;
1160
1161 alg = X509_ALGOR_new();
1162 if (alg == NULL)
1163 goto cleanup2;
1164 alg->algorithm = OBJ_nid2obj(NID_sha1);
1165 alg->parameter = NULL;
1166 alg_len = i2d_X509_ALGOR(alg, NULL);
1167 alg_buf = (unsigned char *)malloc(alg_len);
1168 if (alg_buf == NULL)
1169 goto cleanup2;
1170
1171 digest = ASN1_OCTET_STRING_new();
1172 if (digest == NULL)
1173 goto cleanup2;
1174 ASN1_OCTET_STRING_set(digest, md_data2, (int)md_len2);
1175 digest_len = i2d_ASN1_OCTET_STRING(digest, NULL);
1176 digest_buf = (unsigned char *)malloc(digest_len);
1177 if (digest_buf == NULL)
1178 goto cleanup2;
1179
1273 }
1274 retval = 0;
1275
1276 #ifdef DEBUG_ASN1
1277 if (cms_msg_type == CMS_SIGN_CLIENT) {
1278 print_buffer_bin(*signed_data, *signed_data_len,
1279 "/tmp/client_pkcs7_signeddata");
1280 } else {
1281 if (cms_msg_type == CMS_SIGN_SERVER) {
1282 print_buffer_bin(*signed_data, *signed_data_len,
1283 "/tmp/kdc_pkcs7_signeddata");
1284 } else {
1285 print_buffer_bin(*signed_data, *signed_data_len,
1286 "/tmp/draft9_pkcs7_signeddata");
1287 }
1288 }
1289 #endif
1290
1291 cleanup2:
1292 if (cms_msg_type != CMS_SIGN_DRAFT9)
1293 if (ctx != NULL)
1294 EVP_MD_CTX_free(ctx);
1295 #ifndef WITHOUT_PKCS11
1296 if (id_cryptoctx->pkcs11_method == 1 &&
1297 id_cryptoctx->mech == CKM_RSA_PKCS) {
1298 if (ctx2 != NULL)
1299 EVP_MD_CTX_free(ctx2);
1300 if (digest_buf != NULL)
1301 free(digest_buf);
1302 if (digestInfo_buf != NULL)
1303 free(digestInfo_buf);
1304 if (alg_buf != NULL)
1305 free(alg_buf);
1306 if (digest != NULL)
1307 ASN1_OCTET_STRING_free(digest);
1308 }
1309 #endif
1310 if (alg != NULL)
1311 X509_ALGOR_free(alg);
1312 cleanup:
1313 if (p7 != NULL)
1314 PKCS7_free(p7);
1315 if (sig != NULL)
1316 free(sig);
1317
1318 return retval;
1319 }
1325 pkinit_identity_crypto_context idctx,
1326 int cms_msg_type,
1327 int require_crl_checking,
1328 unsigned char *signed_data,
1329 unsigned int signed_data_len,
1330 unsigned char **data,
1331 unsigned int *data_len,
1332 unsigned char **authz_data,
1333 unsigned int *authz_data_len)
1334 {
1335 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
1336 PKCS7 *p7 = NULL;
1337 BIO *out = NULL;
1338 int flags = PKCS7_NOVERIFY, i = 0;
1339 unsigned int vflags = 0, size = 0;
1340 const unsigned char *p = signed_data;
1341 STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
1342 PKCS7_SIGNER_INFO *si = NULL;
1343 X509 *x = NULL;
1344 X509_STORE *store = NULL;
1345 X509_STORE_CTX *cert_ctx;
1346 STACK_OF(X509) *intermediateCAs = NULL;
1347 STACK_OF(X509_CRL) *revoked = NULL;
1348 STACK_OF(X509) *verified_chain = NULL;
1349 ASN1_OBJECT *oid = NULL;
1350 krb5_external_principal_identifier **krb5_verified_chain = NULL;
1351 krb5_data *authz = NULL;
1352 char buf[DN_BUF_LEN];
1353
1354 #ifdef DEBUG_ASN1
1355 print_buffer_bin(signed_data, signed_data_len,
1356 "/tmp/client_received_pkcs7_signeddata");
1357 #endif
1358
1359 /* Do this early enough to create the shadow OID for pkcs7-data if needed */
1360 oid = pkinit_pkcs7type2oid(plgctx, cms_msg_type);
1361 if (oid == NULL)
1362 goto cleanup;
1363
1364 /* decode received PKCS7 message */
1365 if ((p7 = d2i_PKCS7(NULL, &p, (int)signed_data_len)) == NULL) {
1369 pkiDebug("%s: failed to decode message: %s\n",
1370 __FUNCTION__, ERR_error_string(err, NULL));
1371 goto cleanup;
1372 }
1373
1374 /* verify that the received message is PKCS7 SignedData message */
1375 if (OBJ_obj2nid(p7->type) != NID_pkcs7_signed) {
1376 pkiDebug("Expected id-signedData PKCS7 msg (received type = %d)\n",
1377 OBJ_obj2nid(p7->type));
1378 krb5_set_error_message(context, retval, "wrong oid\n");
1379 goto cleanup;
1380 }
1381
1382 /* setup to verify X509 certificate used to sign PKCS7 message */
1383 if (!(store = X509_STORE_new()))
1384 goto cleanup;
1385
1386 /* check if we are inforcing CRL checking */
1387 vflags = X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
1388 if (require_crl_checking)
1389 X509_STORE_set_verify_cb(store, openssl_callback);
1390 else
1391 X509_STORE_set_verify_cb(store, openssl_callback_ignore_crls);
1392 X509_STORE_set_flags(store, vflags);
1393
1394 /* get the signer's information from the PKCS7 message */
1395 if ((si_sk = PKCS7_get_signer_info(p7)) == NULL)
1396 goto cleanup;
1397 if ((si = sk_PKCS7_SIGNER_INFO_value(si_sk, 0)) == NULL)
1398 goto cleanup;
1399 if ((x = PKCS7_cert_from_signer_info(p7, si)) == NULL)
1400 goto cleanup;
1401
1402 /* create available CRL information (get local CRLs and include CRLs
1403 * received in the PKCS7 message
1404 */
1405 if (idctx->revoked == NULL)
1406 revoked = p7->d.sign->crl;
1407 else if (p7->d.sign->crl == NULL)
1408 revoked = idctx->revoked;
1409 else {
1410 size = sk_X509_CRL_num(idctx->revoked);
1411 revoked = sk_X509_CRL_new_null();
1422 if (idctx->intermediateCAs == NULL)
1423 intermediateCAs = p7->d.sign->cert;
1424 else if (p7->d.sign->cert == NULL)
1425 intermediateCAs = idctx->intermediateCAs;
1426 else {
1427 size = sk_X509_num(idctx->intermediateCAs);
1428 intermediateCAs = sk_X509_new_null();
1429 for (i = 0; i < size; i++) {
1430 sk_X509_push(intermediateCAs,
1431 sk_X509_value(idctx->intermediateCAs, i));
1432 }
1433 size = sk_X509_num(p7->d.sign->cert);
1434 for (i = 0; i < size; i++) {
1435 sk_X509_push(intermediateCAs, sk_X509_value(p7->d.sign->cert, i));
1436 }
1437 }
1438
1439 /* initialize x509 context with the received certificate and
1440 * trusted and intermediate CA chains and CRLs
1441 */
1442 if ((cert_ctx = X509_STORE_CTX_new()) == NULL)
1443 goto cleanup;
1444 if (!X509_STORE_CTX_init(cert_ctx, store, x, intermediateCAs))
1445 goto cleanup;
1446
1447 X509_STORE_CTX_set0_crls(cert_ctx, revoked);
1448
1449 /* add trusted CAs certificates for cert verification */
1450 if (idctx->trustedCAs != NULL)
1451 X509_STORE_CTX_set0_trusted_stack(cert_ctx, idctx->trustedCAs);
1452 else {
1453 pkiDebug("unable to find any trusted CAs\n");
1454 goto cleanup;
1455 }
1456 #ifdef DEBUG_CERTCHAIN
1457 if (intermediateCAs != NULL) {
1458 size = sk_X509_num(intermediateCAs);
1459 pkiDebug("untrusted cert chain of size %d\n", size);
1460 for (i = 0; i < size; i++) {
1461 X509_NAME_oneline(X509_get_subject_name(
1462 sk_X509_value(intermediateCAs, i)), buf, sizeof(buf));
1463 pkiDebug("cert #%d: %s\n", i, buf);
1464 }
1465 }
1466 if (idctx->trustedCAs != NULL) {
1467 size = sk_X509_num(idctx->trustedCAs);
1468 pkiDebug("trusted cert chain of size %d\n", size);
1469 for (i = 0; i < size; i++) {
1470 X509_NAME_oneline(X509_get_subject_name(
1471 sk_X509_value(idctx->trustedCAs, i)), buf, sizeof(buf));
1472 pkiDebug("cert #%d: %s\n", i, buf);
1473 }
1474 }
1475 if (revoked != NULL) {
1476 size = sk_X509_CRL_num(revoked);
1477 pkiDebug("CRL chain of size %d\n", size);
1478 for (i = 0; i < size; i++) {
1479 X509_CRL *crl = sk_X509_CRL_value(revoked, i);
1480 X509_NAME_oneline(X509_CRL_get_issuer(crl), buf, sizeof(buf));
1481 pkiDebug("crls by CA #%d: %s\n", i , buf);
1482 }
1483 }
1484 #endif
1485
1486 i = X509_verify_cert(cert_ctx);
1487 if (i <= 0) {
1488 int j = X509_STORE_CTX_get_error(cert_ctx);
1489
1490 reqctx->received_cert = X509_dup(
1491 X509_STORE_CTX_get_current_cert(cert_ctx));
1492 switch(j) {
1493 case X509_V_ERR_CERT_REVOKED:
1494 retval = KRB5KDC_ERR_REVOKED_CERTIFICATE;
1495 break;
1496 case X509_V_ERR_UNABLE_TO_GET_CRL:
1497 retval = KRB5KDC_ERR_REVOCATION_STATUS_UNKNOWN;
1498 break;
1499 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
1500 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1501 retval = KRB5KDC_ERR_CANT_VERIFY_CERTIFICATE;
1502 break;
1503 default:
1504 retval = KRB5KDC_ERR_INVALID_CERTIFICATE;
1505 }
1506 X509_NAME_oneline(X509_get_subject_name(
1507 reqctx->received_cert), buf, sizeof(buf));
1508 pkiDebug("problem with cert DN = %s (error=%d) %s\n", buf, j,
1509 X509_verify_cert_error_string(j));
1510 krb5_set_error_message(context, retval, "%s\n",
1511 X509_verify_cert_error_string(j));
1512 #ifdef DEBUG_CERTCHAIN
1513 size = sk_X509_num(p7->d.sign->cert);
1514 pkiDebug("received cert chain of size %d\n", size);
1515 for (j = 0; j < size; j++) {
1516 X509 *tmp_cert = sk_X509_value(p7->d.sign->cert, j);
1517 X509_NAME_oneline(X509_get_subject_name(tmp_cert), buf, sizeof(buf));
1518 pkiDebug("cert #%d: %s\n", j, buf);
1519 }
1520 #endif
1521 } else {
1522 /* retrieve verified certificate chain */
1523 if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9)
1524 verified_chain = X509_STORE_CTX_get1_chain(cert_ctx);
1525 }
1526 X509_STORE_CTX_free(cert_ctx);
1527 if (i <= 0)
1528 goto cleanup;
1529
1530 out = BIO_new(BIO_s_mem());
1531 if (cms_msg_type == CMS_SIGN_DRAFT9)
1532 flags |= PKCS7_NOATTR;
1533 if (PKCS7_verify(p7, NULL, store, NULL, out, flags)) {
1534 int valid_oid = 0;
1535
1536 if (!OBJ_cmp(p7->d.sign->contents->type, oid))
1537 valid_oid = 1;
1538 else if (cms_msg_type == CMS_SIGN_DRAFT9) {
1539 /*
1540 * Various implementations of the pa-type 15 request use
1541 * different OIDS. We check that the returned object
1542 * has any of the acceptable OIDs
1543 */
1544 ASN1_OBJECT *client_oid = NULL, *server_oid = NULL, *rsa_oid = NULL;
1545 client_oid = pkinit_pkcs7type2oid(plgctx, CMS_SIGN_CLIENT);
1546 server_oid = pkinit_pkcs7type2oid(plgctx, CMS_SIGN_SERVER);
1547 rsa_oid = pkinit_pkcs7type2oid(plgctx, CMS_ENVEL_SERVER);
1548 if (!OBJ_cmp(p7->d.sign->contents->type, client_oid) ||
1549 !OBJ_cmp(p7->d.sign->contents->type, server_oid) ||
1550 !OBJ_cmp(p7->d.sign->contents->type, rsa_oid))
1551 valid_oid = 1;
1552 }
1553
1554 if (valid_oid)
1555 pkiDebug("PKCS7 Verification successful\n");
1556 else {
1557 const ASN1_OBJECT *etype = p7->d.sign->contents->type;
1558 pkiDebug("wrong oid in eContentType\n");
1559 print_buffer((unsigned char *)OBJ_get0_data(etype),
1560 OBJ_length(etype));
1561 retval = KRB5KDC_ERR_PREAUTH_FAILED;
1562 krb5_set_error_message(context, retval, "wrong oid\n");
1563 goto cleanup;
1564 }
1565 }
1566 else {
1567 unsigned long err = ERR_peek_error();
1568 switch(ERR_GET_REASON(err)) {
1569 case PKCS7_R_DIGEST_FAILURE:
1570 retval = KRB5KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED;
1571 break;
1572 case PKCS7_R_SIGNATURE_FAILURE:
1573 default:
1574 retval = KRB5KDC_ERR_INVALID_SIG;
1575 }
1576 pkiDebug("PKCS7 Verification failure\n");
1577 krb5_set_error_message(context, retval, "%s\n",
1578 ERR_error_string(err, NULL));
1579 goto cleanup;
1580 }
2282 }
2283
2284 return retval;
2285 }
2286
2287 /* ARGSUSED */
2288 krb5_error_code
2289 client_create_dh(krb5_context context,
2290 pkinit_plg_crypto_context plg_cryptoctx,
2291 pkinit_req_crypto_context cryptoctx,
2292 pkinit_identity_crypto_context id_cryptoctx,
2293 int dh_size,
2294 unsigned char **dh_params,
2295 unsigned int *dh_params_len,
2296 unsigned char **dh_pubkey,
2297 unsigned int *dh_pubkey_len)
2298 {
2299 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
2300 unsigned char *buf = NULL;
2301 int dh_err = 0;
2302 ASN1_INTEGER *asn_pub_key = NULL;
2303 BIGNUM *p, *g, *q;
2304 const BIGNUM *pub_key;
2305
2306 if (cryptoctx->dh == NULL) {
2307 if ((cryptoctx->dh = DH_new()) == NULL)
2308 goto cleanup;
2309 if ((g = BN_new()) == NULL || (q = BN_new()) == NULL)
2310 goto cleanup;
2311
2312 switch(dh_size) {
2313 case 1024:
2314 pkiDebug("client uses 1024 DH keys\n");
2315 cryptoctx->dh = make_dhprime(pkinit_1024_dhprime,
2316 sizeof(pkinit_1024_dhprime));
2317 break;
2318 case 2048:
2319 pkiDebug("client uses 2048 DH keys\n");
2320 cryptoctx->dh = make_dhprime(pkinit_2048_dhprime,
2321 sizeof(pkinit_2048_dhprime));
2322 break;
2323 case 4096:
2324 pkiDebug("client uses 4096 DH keys\n");
2325 cryptoctx->dh = make_dhprime(pkinit_4096_dhprime,
2326 sizeof(pkinit_4096_dhprime));
2327 break;
2328 }
2329 if (cryptoctx->dh == NULL)
2330 goto cleanup;
2331 }
2332
2333 DH_generate_key(cryptoctx->dh);
2334 DH_get0_key(cryptoctx->dh, &pub_key, NULL);
2335
2336 /* Solaris Kerberos */
2337 #ifdef DEBUG
2338 DH_check(cryptoctx->dh, &dh_err);
2339 if (dh_err != 0) {
2340 pkiDebug("Warning: dh_check failed with %d\n", dh_err);
2341 if (dh_err & DH_CHECK_P_NOT_PRIME)
2342 pkiDebug("p value is not prime\n");
2343 if (dh_err & DH_CHECK_P_NOT_SAFE_PRIME)
2344 pkiDebug("p value is not a safe prime\n");
2345 if (dh_err & DH_UNABLE_TO_CHECK_GENERATOR)
2346 pkiDebug("unable to check the generator value\n");
2347 if (dh_err & DH_NOT_SUITABLE_GENERATOR)
2348 pkiDebug("the g value is not a generator\n");
2349 }
2350 #endif
2351 #ifdef DEBUG_DH
2352 print_dh(cryptoctx->dh, "client's DH params\n");
2353 print_pubkey(pub_key, "client's pub_key=");
2354 #endif
2355
2356 DH_check_pub_key(cryptoctx->dh, pub_key, &dh_err);
2357 if (dh_err != 0) {
2358 pkiDebug("dh_check_pub_key failed with %d\n", dh_err);
2359 goto cleanup;
2360 }
2361
2362 /* pack DHparams */
2363 /* aglo: usually we could just call i2d_DHparams to encode DH params
2364 * however, PKINIT requires RFC3279 encoding and openssl does pkcs#3.
2365 */
2366 DH_get0_pqg(cryptoctx->dh, (const BIGNUM **)&p, (const BIGNUM **)&q,
2367 (const BIGNUM **)&g);
2368 retval = pkinit_encode_dh_params(p, g, q, dh_params, dh_params_len);
2369 if (retval)
2370 goto cleanup;
2371
2372 /* pack DH public key */
2373 /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this
2374 * encoding shall be used as the contents (the value) of the
2375 * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo
2376 * data element
2377 */
2378 if ((asn_pub_key = BN_to_ASN1_INTEGER(pub_key, NULL)) == NULL)
2379 goto cleanup;
2380 *dh_pubkey_len = i2d_ASN1_INTEGER(asn_pub_key, NULL);
2381 if ((buf = *dh_pubkey = (unsigned char *)
2382 malloc((size_t) *dh_pubkey_len)) == NULL) {
2383 retval = ENOMEM;
2384 goto cleanup;
2385 }
2386 i2d_ASN1_INTEGER(asn_pub_key, &buf);
2387
2388 if (asn_pub_key != NULL)
2389 ASN1_INTEGER_free(asn_pub_key);
2390
2391 retval = 0;
2392 return retval;
2393
2394 cleanup:
2395 if (cryptoctx->dh != NULL)
2396 DH_free(cryptoctx->dh);
2397 cryptoctx->dh = NULL;
2398 if (*dh_params != NULL)
2399 free(*dh_params);
2400 *dh_params = NULL;
2401 if (*dh_pubkey != NULL)
2402 free(*dh_pubkey);
2403 *dh_pubkey = NULL;
2404 if (asn_pub_key != NULL)
2405 ASN1_INTEGER_free(asn_pub_key);
2406
2407 return retval;
2408 }
2409
2410 /* ARGSUSED */
2411 krb5_error_code
2412 client_process_dh(krb5_context context,
2413 pkinit_plg_crypto_context plg_cryptoctx,
2414 pkinit_req_crypto_context cryptoctx,
2415 pkinit_identity_crypto_context id_cryptoctx,
2416 unsigned char *subjectPublicKey_data,
2417 unsigned int subjectPublicKey_length,
2418 unsigned char **client_key,
2419 unsigned int *client_key_len)
2420 {
2421 /* Solaris Kerberos */
2422 krb5_error_code retval = KRB5_PREAUTH_FAILED;
2423 BIGNUM *server_pub_key = NULL;
2424 ASN1_INTEGER *pub_key = NULL;
2425 const unsigned char *p = NULL;
2473 ASN1_INTEGER_free(pub_key);
2474 if (data != NULL)
2475 free (data);
2476
2477 return retval;
2478 }
2479
2480 /* ARGSUSED */
2481 krb5_error_code
2482 server_check_dh(krb5_context context,
2483 pkinit_plg_crypto_context cryptoctx,
2484 pkinit_req_crypto_context req_cryptoctx,
2485 pkinit_identity_crypto_context id_cryptoctx,
2486 krb5_octet_data *dh_params,
2487 int minbits)
2488 {
2489 DH *dh = NULL;
2490 unsigned char *tmp = NULL;
2491 int dh_prime_bits;
2492 krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
2493 const BIGNUM *p, *g, *q, *p2;
2494
2495 tmp = dh_params->data;
2496 dh = DH_new();
2497 dh = pkinit_decode_dh_params(&dh, &tmp, dh_params->length);
2498 if (dh == NULL) {
2499 pkiDebug("failed to decode dhparams\n");
2500 goto cleanup;
2501 }
2502
2503 DH_get0_pqg(dh, &p, &q, &g);
2504
2505 /* KDC SHOULD check to see if the key parameters satisfy its policy */
2506 dh_prime_bits = BN_num_bits(p);
2507 if (minbits && dh_prime_bits < minbits) {
2508 pkiDebug("client sent dh params with %d bits, we require %d\n",
2509 dh_prime_bits, minbits);
2510 goto cleanup;
2511 }
2512
2513 /* check dhparams is group 2 */
2514 DH_get0_pqg(cryptoctx->dh_1024, &p2, NULL, NULL);
2515 if (pkinit_check_dh_params(p2, p, g, q) == 0) {
2516 retval = 0;
2517 goto cleanup;
2518 }
2519
2520 /* check dhparams is group 14 */
2521 DH_get0_pqg(cryptoctx->dh_2048, &p2, NULL, NULL);
2522 if (pkinit_check_dh_params(p2, p, g, q) == 0) {
2523 retval = 0;
2524 goto cleanup;
2525 }
2526
2527 /* check dhparams is group 16 */
2528 DH_get0_pqg(cryptoctx->dh_4096, &p2, NULL, NULL);
2529 if (pkinit_check_dh_params(p2, p, g, q) == 0) {
2530 retval = 0;
2531 goto cleanup;
2532 }
2533
2534 cleanup:
2535 if (retval == 0)
2536 req_cryptoctx->dh = dh;
2537 else
2538 DH_free(dh);
2539
2540 return retval;
2541 }
2542
2543 /* kdc's dh function */
2544 /* ARGSUSED */
2545 krb5_error_code
2546 server_process_dh(krb5_context context,
2547 pkinit_plg_crypto_context plg_cryptoctx,
2548 pkinit_req_crypto_context cryptoctx,
2549 pkinit_identity_crypto_context id_cryptoctx,
2550 unsigned char *data,
2551 unsigned int data_len,
2552 unsigned char **dh_pubkey,
2553 unsigned int *dh_pubkey_len,
2554 unsigned char **server_key,
2555 unsigned int *server_key_len)
2556 {
2557 /* Solaris Kerberos */
2558 krb5_error_code retval = KRB5KRB_ERR_GENERIC;
2559 DH *dh = NULL, *dh_server = NULL;
2560 const BIGNUM *p, *g, *q, *s_pub_key;
2561 BIGNUM *pub_key;
2562 unsigned char *s = NULL;
2563 ASN1_INTEGER *asn_pub_key = NULL;
2564
2565 /* get client's received DH parameters that we saved in server_check_dh */
2566 dh = cryptoctx->dh;
2567
2568 dh_server = DH_new();
2569 if (dh_server == NULL)
2570 goto cleanup;
2571 DH_get0_pqg(dh, &p, &g, &q);
2572 DH_set0_pqg(dh_server, BN_dup(p), BN_dup(g), BN_dup(q));
2573
2574 /* decode client's public key */
2575 s = data;
2576 asn_pub_key = d2i_ASN1_INTEGER(NULL,
2577 (const unsigned char **)&s, (int)data_len);
2578 if (asn_pub_key == NULL)
2579 goto cleanup;
2580 pub_key = ASN1_INTEGER_to_BN(asn_pub_key, NULL);
2581 if (pub_key == NULL)
2582 goto cleanup;
2583 DH_set0_key(dh, pub_key, NULL);
2584 ASN1_INTEGER_free(asn_pub_key);
2585
2586 if (!DH_generate_key(dh_server))
2587 goto cleanup;
2588
2589 /* generate DH session key */
2590 *server_key_len = DH_size(dh_server);
2591 if ((*server_key = (unsigned char *) malloc((size_t)*server_key_len))
2592 == NULL)
2593 goto cleanup;
2594 DH_compute_key(*server_key, pub_key, dh_server);
2595 DH_get0_key(dh_server, &s_pub_key, NULL);
2596
2597 #ifdef DEBUG_DH
2598 print_dh(dh_server, "client&server's DH params\n");
2599 print_pubkey(pub_key, "client's pub_key=");
2600 print_pubkey(s_pub_key, "server's pub_key=");
2601 pkiDebug("server secret key=");
2602 print_buffer(*server_key, *server_key_len);
2603 #endif
2604
2605 /* KDC reply */
2606 /* pack DH public key */
2607 /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this
2608 * encoding shall be used as the contents (the value) of the
2609 * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo
2610 * data element
2611 */
2612 if ((asn_pub_key = BN_to_ASN1_INTEGER(s_pub_key, NULL)) == NULL)
2613 goto cleanup;
2614 *dh_pubkey_len = i2d_ASN1_INTEGER(asn_pub_key, NULL);
2615 if ((s = *dh_pubkey = (unsigned char *) malloc((size_t)*dh_pubkey_len))
2616 == NULL)
2617 goto cleanup;
2618 i2d_ASN1_INTEGER(asn_pub_key, &s);
2619 if (asn_pub_key != NULL)
2620 ASN1_INTEGER_free(asn_pub_key);
2621
2622 retval = 0;
2623
2624 if (dh_server != NULL)
2625 DH_free(dh_server);
2626 return retval;
2627
2628 cleanup:
2629 if (dh_server != NULL)
2630 DH_free(dh_server);
2631 if (*dh_pubkey != NULL)
2632 free(*dh_pubkey);
2633 if (*server_key != NULL)
2634 free(*server_key);
2635
2636 return retval;
2637 }
2638
2639 /*
2640 * Solaris Kerberos:
2641 * Add locking around did_init to make it MT-safe.
2642 */
2643 static krb5_error_code
2644 openssl_init()
2645 {
2646 krb5_error_code ret = 0;
2647 static int did_init = 0;
2648 static k5_mutex_t init_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
2649
2650 ret = k5_mutex_lock(&init_mutex);
2651 if (ret == 0) {
2652 if (!did_init) {
2653 /* initialize openssl routines */
2654 #if OPENSSL_VERSION_NUMBER < 0x10100000L
2655 /*
2656 * As of version 1.1.0, OpenSSL will automatically allocate
2657 * resources as-needed.
2658 */
2659 CRYPTO_malloc_init();
2660 ERR_load_crypto_strings();
2661 OpenSSL_add_all_algorithms();
2662 #endif
2663 did_init++;
2664 }
2665 k5_mutex_unlock(&init_mutex);
2666 }
2667 return (ret);
2668 }
2669
2670 static krb5_error_code
2671 pkinit_encode_dh_params(const BIGNUM *p, const BIGNUM *g, const BIGNUM *q,
2672 unsigned char **buf, unsigned int *buf_len)
2673 {
2674 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
2675 int bufsize = 0, r = 0;
2676 unsigned char *tmp = NULL;
2677 ASN1_INTEGER *ap = NULL, *ag = NULL, *aq = NULL;
2678
2679 if ((ap = BN_to_ASN1_INTEGER(p, NULL)) == NULL)
2680 goto cleanup;
2681 if ((ag = BN_to_ASN1_INTEGER(g, NULL)) == NULL)
2682 goto cleanup;
2683 if ((aq = BN_to_ASN1_INTEGER(q, NULL)) == NULL)
2684 goto cleanup;
2685 bufsize = i2d_ASN1_INTEGER(ap, NULL);
2686 bufsize += i2d_ASN1_INTEGER(ag, NULL);
2687 bufsize += i2d_ASN1_INTEGER(aq, NULL);
2688
2689 r = ASN1_object_size(1, bufsize, V_ASN1_SEQUENCE);
2690
2691 tmp = *buf = (unsigned char *)malloc((size_t) r);
2696
2697 i2d_ASN1_INTEGER(ap, &tmp);
2698 i2d_ASN1_INTEGER(ag, &tmp);
2699 i2d_ASN1_INTEGER(aq, &tmp);
2700
2701 *buf_len = r;
2702
2703 retval = 0;
2704
2705 cleanup:
2706 if (ap != NULL)
2707 ASN1_INTEGER_free(ap);
2708 if (ag != NULL)
2709 ASN1_INTEGER_free(ag);
2710 if (aq != NULL)
2711 ASN1_INTEGER_free(aq);
2712
2713 return retval;
2714 }
2715
2716 #if OPENSSL_VERSION_NUMBER < 0x10100000L
2717
2718 static DH *
2719 pkinit_decode_dh_params(DH ** a, unsigned char **pp, unsigned int len)
2720 {
2721 ASN1_INTEGER ai, *aip = NULL;
2722 long length = (long) len;
2723
2724 M_ASN1_D2I_vars(a, DH *, DH_new);
2725
2726 M_ASN1_D2I_Init();
2727 M_ASN1_D2I_start_sequence();
2728 aip = &ai;
2729 ai.data = NULL;
2730 ai.length = 0;
2731 M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
2732 if (aip == NULL)
2733 return NULL;
2734 else {
2735 (*a)->p = ASN1_INTEGER_to_BN(aip, NULL);
2736 if ((*a)->p == NULL)
2737 return NULL;
2757 }
2758 M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
2759 if (aip == NULL)
2760 return NULL;
2761 else {
2762 (*a)->q = ASN1_INTEGER_to_BN(aip, NULL);
2763 if ((*a)->q == NULL)
2764 return NULL;
2765 if (ai.data != NULL) {
2766 OPENSSL_free(ai.data);
2767 ai.data = NULL;
2768 ai.length = 0;
2769 }
2770
2771 }
2772 M_ASN1_D2I_end_sequence();
2773 M_ASN1_D2I_Finish(a, DH_free, 0);
2774
2775 }
2776
2777 #else
2778
2779 /*
2780 * This is taken from the internal dh_asn1.c file in OpenSSL 1.1, modified to
2781 * make q an optional field.
2782 */
2783
2784 typedef struct {
2785 ASN1_BIT_STRING *seed;
2786 BIGNUM *counter;
2787 } int_dhvparams;
2788
2789 typedef struct {
2790 BIGNUM *p;
2791 BIGNUM *q;
2792 BIGNUM *g;
2793 BIGNUM *j;
2794 int_dhvparams *vparams;
2795 } int_dhx942_dh;
2796
2797 ASN1_SEQUENCE(DHvparams) = {
2798 ASN1_SIMPLE(int_dhvparams, seed, ASN1_BIT_STRING),
2799 ASN1_SIMPLE(int_dhvparams, counter, BIGNUM)
2800 } static_ASN1_SEQUENCE_END_name(int_dhvparams, DHvparams)
2801
2802 ASN1_SEQUENCE(DHxparams) = {
2803 ASN1_SIMPLE(int_dhx942_dh, p, BIGNUM),
2804 ASN1_SIMPLE(int_dhx942_dh, g, BIGNUM),
2805 ASN1_OPT(int_dhx942_dh, q, BIGNUM),
2806 ASN1_OPT(int_dhx942_dh, j, BIGNUM),
2807 ASN1_OPT(int_dhx942_dh, vparams, DHvparams),
2808 } static_ASN1_SEQUENCE_END_name(int_dhx942_dh, DHxparams)
2809
2810 static DH *
2811 pkinit_decode_dh_params(DH **a, unsigned char **pp, unsigned int len)
2812 {
2813 int_dhx942_dh *params;
2814 DH *dh = *a;
2815
2816 if (dh == NULL)
2817 return NULL;
2818
2819 params = (int_dhx942_dh *)ASN1_item_d2i(NULL,
2820 (const unsigned char **)pp, len, ASN1_ITEM_rptr(DHxparams));
2821 if (params == NULL) {
2822 DH_free(dh);
2823 return NULL;
2824 }
2825
2826 DH_set0_pqg(dh, params->p, params->q, params->g);
2827 params->p = params->q = params->g = NULL;
2828 ASN1_item_free((ASN1_VALUE *)params, ASN1_ITEM_rptr(DHxparams));
2829 return dh;
2830 }
2831
2832 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
2833
2834 static krb5_error_code
2835 pkinit_create_sequence_of_principal_identifiers(
2836 krb5_context context,
2837 pkinit_plg_crypto_context plg_cryptoctx,
2838 pkinit_req_crypto_context req_cryptoctx,
2839 pkinit_identity_crypto_context id_cryptoctx,
2840 int type,
2841 krb5_data **out_data)
2842 {
2843 krb5_error_code retval = KRB5KRB_ERR_GENERIC;
2844 krb5_external_principal_identifier **krb5_trusted_certifiers = NULL;
2845 krb5_data *td_certifiers = NULL, *data = NULL;
2846 krb5_typed_data **typed_data = NULL;
2847
2848 switch(type) {
2849 case TD_TRUSTED_CERTIFIERS:
2850 retval = create_krb5_trustedCertifiers(context, plg_cryptoctx,
2851 req_cryptoctx, id_cryptoctx, &krb5_trusted_certifiers);
2852 if (retval) {
2853 pkiDebug("create_krb5_trustedCertifiers failed\n");
2958
2959 return retval;
2960 }
2961
2962 /* ARGSUSED */
2963 krb5_error_code
2964 pkinit_create_td_dh_parameters(krb5_context context,
2965 pkinit_plg_crypto_context plg_cryptoctx,
2966 pkinit_req_crypto_context req_cryptoctx,
2967 pkinit_identity_crypto_context id_cryptoctx,
2968 pkinit_plg_opts *opts,
2969 krb5_data **out_data)
2970 {
2971 /* Solaris Kerberos */
2972 krb5_error_code retval = KRB5KRB_ERR_GENERIC;
2973 unsigned int buf1_len = 0, buf2_len = 0, buf3_len = 0, i = 0;
2974 unsigned char *buf1 = NULL, *buf2 = NULL, *buf3 = NULL;
2975 krb5_typed_data **typed_data = NULL;
2976 krb5_data *data = NULL, *encoded_algId = NULL;
2977 krb5_algorithm_identifier **algId = NULL;
2978 const BIGNUM *p, *q, *g;
2979
2980 /* Solaris Kerberos */
2981 if (opts->dh_min_bits > 4096) {
2982 retval = EINVAL;
2983 goto cleanup;
2984 }
2985
2986 if (opts->dh_min_bits <= 1024) {
2987 DH_get0_pqg(plg_cryptoctx->dh_1024, &p, &q, &g);
2988 retval = pkinit_encode_dh_params(p, g, q, &buf1, &buf1_len);
2989 if (retval)
2990 goto cleanup;
2991 }
2992 if (opts->dh_min_bits <= 2048) {
2993 DH_get0_pqg(plg_cryptoctx->dh_2048, &p, &q, &g);
2994 retval = pkinit_encode_dh_params(p, g, q, &buf2, &buf2_len);
2995 if (retval)
2996 goto cleanup;
2997 }
2998 DH_get0_pqg(plg_cryptoctx->dh_4096, &p, &q, &g);
2999 retval = pkinit_encode_dh_params(p, g, q, &buf3, &buf3_len);
3000 if (retval)
3001 goto cleanup;
3002
3003 if (opts->dh_min_bits <= 1024) {
3004 algId = malloc(4 * sizeof(krb5_algorithm_identifier *));
3005 if (algId == NULL)
3006 goto cleanup;
3007 algId[3] = NULL;
3008 algId[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
3009 if (algId[0] == NULL)
3010 goto cleanup;
3011 algId[0]->parameters.data = (unsigned char *)malloc(buf2_len);
3012 if (algId[0]->parameters.data == NULL)
3013 goto cleanup;
3014 (void) memcpy(algId[0]->parameters.data, buf2, buf2_len);
3015 algId[0]->parameters.length = buf2_len;
3016 algId[0]->algorithm = dh_oid;
3017
3018 algId[1] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
3019 if (algId[1] == NULL)
3173 if (is == NULL)
3174 goto cleanup;
3175
3176 status = X509_NAME_cmp(X509_get_issuer_name(kdc_cert), is->issuer);
3177 if (!status) {
3178 status = ASN1_INTEGER_cmp(X509_get_serialNumber(kdc_cert), is->serial);
3179 if (!status)
3180 *valid_kdcPkId = 1;
3181 }
3182
3183 retval = 0;
3184 cleanup:
3185 X509_NAME_free(is->issuer);
3186 ASN1_INTEGER_free(is->serial);
3187 free(is);
3188
3189 return retval;
3190 }
3191
3192 static int
3193 pkinit_check_dh_params(const BIGNUM *p1, const BIGNUM *p2, const BIGNUM *g1,
3194 const BIGNUM *q1)
3195 {
3196 BIGNUM *g2 = NULL, *q2 = NULL;
3197 /* Solaris Kerberos */
3198 int retval = EINVAL;
3199
3200 if (!BN_cmp(p1, p2)) {
3201 g2 = BN_new();
3202 BN_set_word(g2, DH_GENERATOR_2);
3203 if (!BN_cmp(g1, g2)) {
3204 q2 = BN_new();
3205 BN_rshift1(q2, p1);
3206 if (!BN_cmp(q1, q2)) {
3207 pkiDebug("good %d dhparams\n", BN_num_bits(p1));
3208 retval = 0;
3209 } else
3210 pkiDebug("bad group 2 q dhparameter\n");
3211 BN_free(q2);
3212 } else
3213 pkiDebug("bad g dhparameter\n");
3214 BN_free(g2);
3218 return retval;
3219 }
3220
3221 /* ARGSUSED */
3222 krb5_error_code
3223 pkinit_process_td_dh_params(krb5_context context,
3224 pkinit_plg_crypto_context cryptoctx,
3225 pkinit_req_crypto_context req_cryptoctx,
3226 pkinit_identity_crypto_context id_cryptoctx,
3227 krb5_algorithm_identifier **algId,
3228 int *new_dh_size)
3229 {
3230 krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
3231 int i = 0, use_sent_dh = 0, ok = 0;
3232
3233 pkiDebug("dh parameters\n");
3234
3235 while (algId[i] != NULL) {
3236 DH *dh = NULL;
3237 unsigned char *tmp = NULL;
3238 const BIGNUM *p, *g, *q, *p2;
3239 int dh_prime_bits = 0;
3240
3241 if (algId[i]->algorithm.length != dh_oid.length ||
3242 memcmp(algId[i]->algorithm.data, dh_oid.data, dh_oid.length))
3243 goto cleanup;
3244
3245 tmp = algId[i]->parameters.data;
3246 dh = DH_new();
3247 dh = pkinit_decode_dh_params(&dh, &tmp, algId[i]->parameters.length);
3248 dh_prime_bits = DH_bits(dh);
3249 pkiDebug("client sent %d DH bits server prefers %d DH bits\n",
3250 *new_dh_size, dh_prime_bits);
3251 DH_get0_pqg(dh, &p, &q, &g);
3252 switch(dh_prime_bits) {
3253 case 1024:
3254 DH_get0_pqg(cryptoctx->dh_1024, &p2, NULL, NULL);
3255 if (pkinit_check_dh_params(p2, p, g, q) == 0) {
3256 *new_dh_size = 1024;
3257 ok = 1;
3258 }
3259 break;
3260 case 2048:
3261 DH_get0_pqg(cryptoctx->dh_2048, &p2, NULL, NULL);
3262 if (pkinit_check_dh_params(p2, p, g, q) == 0) {
3263 *new_dh_size = 2048;
3264 ok = 1;
3265 }
3266 break;
3267 case 4096:
3268 DH_get0_pqg(cryptoctx->dh_4096, &p2, NULL, NULL);
3269 if (pkinit_check_dh_params(p2, p, g, q) == 0) {
3270 *new_dh_size = 4096;
3271 ok = 1;
3272 }
3273 break;
3274 default:
3275 break;
3276 }
3277 if (!ok) {
3278 DH_check(dh, &retval);
3279 if (retval != 0) {
3280 pkiDebug("DH parameters provided by server are unacceptable\n");
3281 retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
3282 }
3283 else {
3284 use_sent_dh = 1;
3285 ok = 1;
3286 }
3287 }
3288 if (!use_sent_dh)
3289 DH_free(dh);
3309 /* ARGSUSED */
3310 static int
3311 openssl_callback(int ok, X509_STORE_CTX * ctx)
3312 {
3313 #ifdef DEBUG
3314 if (!ok) {
3315 char buf[DN_BUF_LEN];
3316
3317 X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), buf, sizeof(buf));
3318 pkiDebug("cert = %s\n", buf);
3319 pkiDebug("callback function: %d (%s)\n", ctx->error,
3320 X509_verify_cert_error_string(ctx->error));
3321 }
3322 #endif
3323 return ok;
3324 }
3325
3326 static int
3327 openssl_callback_ignore_crls(int ok, X509_STORE_CTX * ctx)
3328 {
3329 if (!ok)
3330 return (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_UNABLE_TO_GET_CRL);
3331 return ok;
3332 }
3333
3334 static ASN1_OBJECT *
3335 pkinit_pkcs7type2oid(pkinit_plg_crypto_context cryptoctx, int pkcs7_type)
3336 {
3337 int nid;
3338
3339 switch (pkcs7_type) {
3340 case CMS_SIGN_CLIENT:
3341 return cryptoctx->id_pkinit_authData;
3342 case CMS_SIGN_DRAFT9:
3343 /*
3344 * Delay creating this OID until we know we need it.
3345 * It shadows an existing OpenSSL oid. If it
3346 * is created too early, it breaks things like
3347 * the use of pkcs12 (which uses pkcs7 structures).
3348 * We need this shadow version because our code
3349 * depends on the "other" type to be unknown to the
3350 * OpenSSL code.
3499 ASN1_put_object(&p, 1, (int)(orig_len+oid_len),
3500 V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
3501
3502 i2d_ASN1_OBJECT(oid, &p);
3503
3504 ASN1_put_object(&p, 1, (int)data_len, 0, V_ASN1_CONTEXT_SPECIFIC);
3505 (void) memcpy(p, data, data_len);
3506
3507 *out_len = tot_len;
3508
3509 return 0;
3510 }
3511 #endif
3512
3513 static int
3514 prepare_enc_data(unsigned char *indata,
3515 int indata_len,
3516 unsigned char **outdata,
3517 int *outdata_len)
3518 {
3519 int tag, class;
3520 long tlen, slen;
3521 const uint8_t *p = indata, *oldp;
3522
3523 /* Top-bit set means that the conversion failed. */
3524 if (ASN1_get_object(&p, &slen, &tag, &class, indata_len) & 0x80)
3525 return EINVAL;
3526 if (tag != V_ASN1_SEQUENCE)
3527 return EINVAL;
3528
3529 oldp = p;
3530 if (ASN1_get_object(&p, &tlen, &tag, &class, slen) & 0x80)
3531 return EINVAL;
3532 p += tlen;
3533 slen -= (p - oldp);
3534
3535 if (ASN1_get_object(&p, &tlen, &tag, &class, slen) & 0x80)
3536 return EINVAL;
3537
3538 *outdata = malloc(tlen);
3539 if (*outdata == NULL)
3540 return ENOMEM;
3541 memcpy(*outdata, p, tlen);
3542 *outdata_len = tlen;
3543
3544 return 0;
3545 }
3546
3547 #ifndef WITHOUT_PKCS11
3548 static void *
3549 pkinit_C_LoadModule(const char *modname, CK_FUNCTION_LIST_PTR_PTR p11p)
3550 {
3551 void *handle;
3552 CK_RV (*getflist)(CK_FUNCTION_LIST_PTR_PTR);
3553
3554 pkiDebug("loading module \"%s\"... ", modname);
3555 /* Solaris Kerberos */
3556 handle = dlopen(modname, RTLD_NOW | RTLD_GROUP);
3557 if (handle == NULL) {
3558 pkiDebug("not found\n");
3559 return NULL;
3560 }
3561 getflist = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR)) dlsym(handle, "C_GetFunctionList");
3562 if (getflist == NULL || (*getflist)(p11p) != CKR_OK) {
3563 (void) dlclose(handle);
4555 * You must call pkinit_get_certs before calling pkinit_find_private_key
4556 * (that's because we need the ID of the private key)
4557 *
4558 * pkcs11 says the id of the key doesn't have to match that of the cert, but
4559 * I can't figure out any other way to decide which key to use.
4560 *
4561 * We should only find one key that fits all the requirements.
4562 * If there are more than one, we just take the first one.
4563 */
4564
4565 /* ARGSUSED */
4566 krb5_error_code
4567 pkinit_find_private_key(pkinit_identity_crypto_context id_cryptoctx,
4568 CK_ATTRIBUTE_TYPE usage,
4569 CK_OBJECT_HANDLE *objp)
4570 {
4571 CK_OBJECT_CLASS cls;
4572 CK_ATTRIBUTE attrs[4];
4573 CK_ULONG count;
4574 CK_KEY_TYPE keytype;
4575 RSA *rsa;
4576 unsigned int nattrs = 0;
4577 int r;
4578 #ifdef PKINIT_USE_KEY_USAGE
4579 CK_BBOOL true_false;
4580 #endif
4581
4582 cls = CKO_PRIVATE_KEY;
4583 attrs[nattrs].type = CKA_CLASS;
4584 attrs[nattrs].pValue = &cls;
4585 attrs[nattrs].ulValueLen = sizeof cls;
4586 nattrs++;
4587
4588 #ifdef PKINIT_USE_KEY_USAGE
4589 /*
4590 * Some cards get confused if you try to specify a key usage,
4591 * so don't, and hope for the best. This will fail if you have
4592 * several keys with the same id and different usages but I have
4593 * not seen this on real cards.
4594 */
4595 true_false = TRUE;
4616 pkinit_pkcs11_code_to_text(r));
4617 return KRB5KDC_ERR_PREAUTH_FAILED;
4618 }
4619
4620 r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1, &count);
4621 id_cryptoctx->p11->C_FindObjectsFinal(id_cryptoctx->session);
4622 pkiDebug("found %d private keys (%s)\n", (int) count, pkinit_pkcs11_code_to_text(r));
4623
4624 /*
4625 * Solaris Kerberos:
4626 * The CKA_ID may not be correctly set for the private key. For e.g. when
4627 * storing a private key in softtoken pktool(1) doesn't generate or store
4628 * a CKA_ID for the private key. Another way to identify the private key is
4629 * to look for a private key with the same RSA modulus as the public key
4630 * in the certificate.
4631 */
4632 if (r == CKR_OK && count != 1) {
4633
4634 EVP_PKEY *priv;
4635 X509 *cert;
4636 const BIGNUM *rsan;
4637 unsigned int n_len;
4638 unsigned char *n_bytes;
4639
4640 cert = sk_X509_value(id_cryptoctx->my_certs, 0);
4641 priv = X509_get_pubkey(cert);
4642 if (priv == NULL) {
4643 pkiDebug("Failed to extract pub key from cert\n");
4644 return KRB5KDC_ERR_PREAUTH_FAILED;
4645 }
4646
4647 nattrs = 0;
4648 cls = CKO_PRIVATE_KEY;
4649 attrs[nattrs].type = CKA_CLASS;
4650 attrs[nattrs].pValue = &cls;
4651 attrs[nattrs].ulValueLen = sizeof cls;
4652 nattrs++;
4653
4654 #ifdef PKINIT_USE_KEY_USAGE
4655 true_false = TRUE;
4656 attrs[nattrs].type = usage;
4657 attrs[nattrs].pValue = &true_false;
4658 attrs[nattrs].ulValueLen = sizeof true_false;
4659 nattrs++;
4660 #endif
4661
4662 keytype = CKK_RSA;
4663 attrs[nattrs].type = CKA_KEY_TYPE;
4664 attrs[nattrs].pValue = &keytype;
4665 attrs[nattrs].ulValueLen = sizeof keytype;
4666 nattrs++;
4667
4668 #if OPENSSL_VERSION_NUMBER < 0x10100000L
4669 rsa = priv->pkey.rsa;
4670 rsan = rsa->n;
4671 n_len = BN_num_bytes(rsan);
4672 #else
4673 rsa = EVP_PKEY_get0_RSA(priv);
4674 RSA_get0_key(rsa, &rsan, NULL, NULL);
4675 n_len = RSA_size(rsa);
4676 #endif
4677 n_bytes = (unsigned char *) malloc((size_t) n_len);
4678 if (n_bytes == NULL) {
4679 return (ENOMEM);
4680 }
4681
4682 if (BN_bn2bin(rsan, n_bytes) == 0) {
4683 free (n_bytes);
4684 pkiDebug("zero-byte key modulus\n");
4685 return KRB5KDC_ERR_PREAUTH_FAILED;
4686 }
4687
4688 attrs[nattrs].type = CKA_MODULUS;
4689 attrs[nattrs].ulValueLen = n_len;
4690 attrs[nattrs].pValue = n_bytes;
4691
4692 nattrs++;
4693
4694 r = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs, nattrs);
4695 free (n_bytes);
4696 if (r != CKR_OK) {
4697 pkiDebug("krb5_pkinit_sign_data: C_FindObjectsInit: %s\n",
4698 pkinit_pkcs11_code_to_text(r));
4699 return KRB5KDC_ERR_PREAUTH_FAILED;
4700 }
4701
4702 r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1, &count);
4971 /* Solaris Kerberos */
4972 int len;
4973 unsigned char *buf = NULL;
4974 int buf_len = 0;
4975
4976 /* Solaris Kerberos */
4977 if (out_data == NULL || out_data_len == NULL)
4978 return EINVAL;
4979
4980 if (cert && !X509_check_private_key(cert, pkey)) {
4981 pkiDebug("private key does not match certificate\n");
4982 /* Solaris Kerberos */
4983 return EINVAL;
4984 }
4985
4986 buf_len = EVP_PKEY_size(pkey);
4987 buf = (unsigned char *)malloc((size_t) buf_len + 10);
4988 if (buf == NULL)
4989 return ENOMEM;
4990
4991 len = EVP_PKEY_decrypt_old(buf, data, (int)data_len, pkey);
4992 if (len <= 0) {
4993 pkiDebug("unable to decrypt received data (len=%d)\n", data_len);
4994 /* Solaris Kerberos */
4995 free(buf);
4996 return KRB5KRB_ERR_GENERIC;
4997 }
4998 *out_data = buf;
4999 *out_data_len = len;
5000
5001 return 0;
5002 }
5003
5004 static krb5_error_code
5005 create_signature(unsigned char **sig, unsigned int *sig_len,
5006 unsigned char *data, unsigned int data_len, EVP_PKEY *pkey)
5007 {
5008 krb5_error_code retval = ENOMEM;
5009 EVP_MD_CTX *md_ctx;
5010
5011 if (pkey == NULL)
5012 /* Solaris Kerberos */
5013 return EINVAL;
5014
5015 if ((md_ctx = EVP_MD_CTX_new()) == NULL)
5016 return EINVAL;
5017
5018 EVP_VerifyInit(md_ctx, EVP_sha1());
5019 EVP_SignUpdate(md_ctx, data, data_len);
5020 *sig_len = EVP_PKEY_size(pkey);
5021 if ((*sig = (unsigned char *) malloc((size_t) *sig_len)) == NULL)
5022 goto cleanup;
5023 EVP_SignFinal(md_ctx, *sig, sig_len, pkey);
5024
5025 retval = 0;
5026
5027 cleanup:
5028 EVP_MD_CTX_free(md_ctx);
5029
5030 return retval;
5031 }
5032
5033 /*
5034 * Note:
5035 * This is not the routine the KDC uses to get its certificate.
5036 * This routine is intended to be called by the client
5037 * to obtain the KDC's certificate from some local storage
5038 * to be sent as a hint in its request to the KDC.
5039 */
5040 /* ARGSUSED */
5041 krb5_error_code
5042 pkinit_get_kdc_cert(krb5_context context,
5043 pkinit_plg_crypto_context plg_cryptoctx,
5044 pkinit_req_crypto_context req_cryptoctx,
5045 pkinit_identity_crypto_context id_cryptoctx,
5046 krb5_principal princ)
5047 {
5048 /* Solaris Kerberos */
6294 krb5_cas[i]->subjectName.length = 0;
6295 krb5_cas[i]->subjectName.data = NULL;
6296
6297 xn = X509_get_subject_name(x);
6298 len = i2d_X509_NAME(xn, NULL);
6299 if ((p = krb5_cas[i]->subjectName.data = (unsigned char *)malloc((size_t) len)) == NULL)
6300 goto cleanup;
6301 i2d_X509_NAME(xn, &p);
6302 krb5_cas[i]->subjectName.length = len;
6303
6304 /* fill-in issuerAndSerialNumber */
6305 krb5_cas[i]->issuerAndSerialNumber.length = 0;
6306 krb5_cas[i]->issuerAndSerialNumber.magic = 0;
6307 krb5_cas[i]->issuerAndSerialNumber.data = NULL;
6308
6309 #ifdef LONGHORN_BETA_COMPAT
6310 if (longhorn == 0) { /* XXX Longhorn doesn't like this */
6311 #endif
6312 is = PKCS7_ISSUER_AND_SERIAL_new();
6313 X509_NAME_set(&is->issuer, X509_get_issuer_name(x));
6314 ASN1_INTEGER_free(is->serial);
6315 is->serial = ASN1_INTEGER_dup(X509_get_serialNumber(x));
6316 len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
6317 if ((p = krb5_cas[i]->issuerAndSerialNumber.data =
6318 (unsigned char *)malloc((size_t) len)) == NULL)
6319 goto cleanup;
6320 i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
6321 krb5_cas[i]->issuerAndSerialNumber.length = len;
6322 #ifdef LONGHORN_BETA_COMPAT
6323 }
6324 #endif
6325
6326 /* fill-in subjectKeyIdentifier */
6327 krb5_cas[i]->subjectKeyIdentifier.length = 0;
6328 krb5_cas[i]->subjectKeyIdentifier.magic = 0;
6329 krb5_cas[i]->subjectKeyIdentifier.data = NULL;
6330
6331
6332 #ifdef LONGHORN_BETA_COMPAT
6333 if (longhorn == 0) { /* XXX Longhorn doesn't like this */
6334 #endif
6335 if (X509_get_ext_by_NID(x, NID_subject_key_identifier, -1) >= 0) {
6499 krb5_cas[i]->choice = choice_trusted_cas_principalName;
6500 break;
6501 case choice_trusted_cas_caName:
6502 krb5_cas[i]->choice = choice_trusted_cas_caName;
6503 krb5_cas[i]->u.caName.data = NULL;
6504 krb5_cas[i]->u.caName.length = 0;
6505 xn = X509_get_subject_name(x);
6506 len = i2d_X509_NAME(xn, NULL);
6507 if ((p = krb5_cas[i]->u.caName.data =
6508 (unsigned char *)malloc((size_t) len)) == NULL)
6509 goto cleanup;
6510 i2d_X509_NAME(xn, &p);
6511 krb5_cas[i]->u.caName.length = len;
6512 break;
6513 case choice_trusted_cas_issuerAndSerial:
6514 krb5_cas[i]->choice = choice_trusted_cas_issuerAndSerial;
6515 krb5_cas[i]->u.issuerAndSerial.data = NULL;
6516 krb5_cas[i]->u.issuerAndSerial.length = 0;
6517 is = PKCS7_ISSUER_AND_SERIAL_new();
6518 X509_NAME_set(&is->issuer, X509_get_issuer_name(x));
6519 ASN1_INTEGER_free(is->serial);
6520 is->serial = ASN1_INTEGER_dup(X509_get_serialNumber(x));
6521 len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
6522 if ((p = krb5_cas[i]->u.issuerAndSerial.data =
6523 (unsigned char *)malloc((size_t) len)) == NULL)
6524 goto cleanup;
6525 i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
6526 krb5_cas[i]->u.issuerAndSerial.length = len;
6527 if (is != NULL) {
6528 if (is->issuer != NULL)
6529 X509_NAME_free(is->issuer);
6530 if (is->serial != NULL)
6531 ASN1_INTEGER_free(is->serial);
6532 free(is);
6533 }
6534 break;
6535 default: break;
6536 }
6537 }
6538 retval = 0;
6539 *ids = krb5_cas;
6540 cleanup:
6549 create_issuerAndSerial(krb5_context context,
6550 pkinit_plg_crypto_context plg_cryptoctx,
6551 pkinit_req_crypto_context req_cryptoctx,
6552 pkinit_identity_crypto_context id_cryptoctx,
6553 unsigned char **out,
6554 unsigned int *out_len)
6555 {
6556 unsigned char *p = NULL;
6557 PKCS7_ISSUER_AND_SERIAL *is = NULL;
6558 int len = 0;
6559 krb5_error_code retval = ENOMEM;
6560 X509 *cert = req_cryptoctx->received_cert;
6561
6562 *out = NULL;
6563 *out_len = 0;
6564 if (req_cryptoctx->received_cert == NULL)
6565 return 0;
6566
6567 is = PKCS7_ISSUER_AND_SERIAL_new();
6568 X509_NAME_set(&is->issuer, X509_get_issuer_name(cert));
6569 ASN1_INTEGER_free(is->serial);
6570 is->serial = ASN1_INTEGER_dup(X509_get_serialNumber(cert));
6571 len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
6572 if ((p = *out = (unsigned char *)malloc((size_t) len)) == NULL)
6573 goto cleanup;
6574 i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
6575 *out_len = len;
6576 retval = 0;
6577
6578 cleanup:
6579 X509_NAME_free(is->issuer);
6580 ASN1_INTEGER_free(is->serial);
6581 free(is);
6582
6583 return retval;
6584 }
6585
6586 static int
6587 pkcs7_decrypt(krb5_context context,
6588 pkinit_identity_crypto_context id_cryptoctx,
6589 PKCS7 *p7,
6590 BIO *data)
6735 xalg=p7->d.enveloped->enc_data->algorithm;
6736 #endif
6737
6738 if ((etmp=BIO_new(BIO_f_cipher())) == NULL) {
6739 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
6740 goto cleanup;
6741 }
6742
6743 /* It was encrypted, we need to decrypt the secret key
6744 * with the private key */
6745
6746 /* Find the recipientInfo which matches the passed certificate
6747 * (if any)
6748 */
6749
6750 if (cert) {
6751 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
6752 int tmp_ret = 0;
6753 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
6754 tmp_ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
6755 X509_get_issuer_name(cert));
6756 if (!tmp_ret) {
6757 tmp_ret = ASN1_INTEGER_cmp(X509_get_serialNumber(cert),
6758 ri->issuer_and_serial->serial);
6759 if (!tmp_ret)
6760 break;
6761 }
6762 ri=NULL;
6763 }
6764 if (ri == NULL) {
6765 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
6766 PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
6767 goto cleanup;
6768 }
6769
6770 }
6771
6772 /* If we haven't got a certificate try each ri in turn */
6773
6774 if (cert == NULL) {
6775 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
6776 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
6777 jj = pkinit_decode_data(context, id_cryptoctx,
6778 (unsigned char *)ASN1_STRING_get0_data(ri->enc_key),
6779 ASN1_STRING_length(ri->enc_key),
6780 &tmp, &tmp_len);
6781 if (jj) {
6782 PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB);
6783 goto cleanup;
6784 }
6785
6786 if (!jj && tmp_len > 0) {
6787 jj = tmp_len;
6788 break;
6789 }
6790
6791 ERR_clear_error();
6792 ri = NULL;
6793 }
6794
6795 if (ri == NULL) {
6796 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
6797 goto cleanup;
6798 }
6799 }
6800 else {
6801 jj = pkinit_decode_data(context, id_cryptoctx,
6802 (unsigned char *)ASN1_STRING_get0_data(ri->enc_key),
6803 ASN1_STRING_length(ri->enc_key),
6804 &tmp, &tmp_len);
6805 /* Solaris Kerberos: tmp_len is unsigned. Cannot be < 0 */
6806 if (jj || tmp_len == 0) {
6807 PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB);
6808 goto cleanup;
6809 }
6810 jj = tmp_len;
6811 }
6812
6813 evp_ctx=NULL;
6814 BIO_get_cipher_ctx(etmp,&evp_ctx);
6815 if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0)
6816 goto cleanup;
6817 if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
6818 goto cleanup;
6819
6820 if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) {
6821 /* Some S/MIME clients don't use the same key
6822 * and effective key length. The key length is
6823 * determined by the size of the decrypted RSA key.
6824 */
6825 if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, (int)jj)) {
6826 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
6827 PKCS7_R_DECRYPT_ERROR);
6828 goto cleanup;
6829 }
6830 }
6831 if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0)
6832 goto cleanup;
6833
6834 OPENSSL_cleanse(tmp,jj);
6835
6836 if (out == NULL)
6837 out=etmp;
6838 else
6839 BIO_push(out,etmp);
6840 etmp=NULL;
6841
6842 if (data_body->length > 0)
6843 bio = BIO_new_mem_buf(data_body->data, data_body->length);
6844 else {
6845 bio=BIO_new(BIO_s_mem());
6846 BIO_set_mem_eof_return(bio,0);
6847 }
|