svn rev #23493: branches/anonymous/src/plugins/preauth/pkinit/

hartmans@MIT.EDU hartmans at MIT.EDU
Wed Dec 23 16:09:53 EST 2009


http://src.mit.edu/fisheye/changelog/krb5/?cs=23493
Commit By: hartmans
Log Message:
Implement support for unsigned pkinit messages.

* cms_signeddata_verify will take a ContentInfo as well as SignedData and returns an indication of whether a message is signed
* Accept unsigned authpacks in the  anonymous case.


Changed Files:
U   branches/anonymous/src/plugins/preauth/pkinit/pkinit_clnt.c
U   branches/anonymous/src/plugins/preauth/pkinit/pkinit_crypto.h
U   branches/anonymous/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
U   branches/anonymous/src/plugins/preauth/pkinit/pkinit_srv.c
Modified: branches/anonymous/src/plugins/preauth/pkinit/pkinit_clnt.c
===================================================================
--- branches/anonymous/src/plugins/preauth/pkinit/pkinit_clnt.c	2009-12-23 21:09:50 UTC (rev 23492)
+++ branches/anonymous/src/plugins/preauth/pkinit/pkinit_clnt.c	2009-12-23 21:09:53 UTC (rev 23493)
@@ -61,7 +61,8 @@
 pkinit_as_req_create(krb5_context context, pkinit_context plgctx,
                      pkinit_req_context reqctx, krb5_timestamp ctsec,
                      krb5_int32 cusec, krb5_ui_4 nonce,
-                     const krb5_checksum *cksum, krb5_principal server,
+                     const krb5_checksum *cksum,
+                     krb5_principal client, krb5_principal server,
                      krb5_data **as_req);
 
 static krb5_error_code
@@ -139,7 +140,7 @@
     nonce = request->nonce;
 
     retval = pkinit_as_req_create(context, plgctx, reqctx, ctsec, cusec,
-                                  nonce, &cksum, request->server, &out_data);
+                                  nonce, &cksum, request->client, request->server, &out_data);
     if (retval || !out_data->length) {
         pkiDebug("error %d on pkinit_as_req_create; aborting PKINIT\n",
                  (int) retval);
@@ -218,6 +219,7 @@
                      krb5_int32 cusec,
                      krb5_ui_4 nonce,
                      const krb5_checksum * cksum,
+                     krb5_principal client,
                      krb5_principal server,
                      krb5_data ** as_req)
 {
@@ -344,10 +346,17 @@
             retval = ENOMEM;
             goto cleanup;
         }
-        retval = cms_signeddata_create(context, plgctx->cryptoctx,
-                                       reqctx->cryptoctx, reqctx->idctx, CMS_SIGN_CLIENT, 1,
-                                       (unsigned char *)coded_auth_pack->data, coded_auth_pack->length,
-                                       &req->signedAuthPack.data, &req->signedAuthPack.length);
+        /*For the new protocol, we support anonymous*/
+        if (krb5_principal_compare_any_realm(context, client,
+                                             krb5_anonymous_principal()))
+            retval = cms_contentinfo_create(context, plgctx->cryptoctx,
+                                            reqctx->cryptoctx, reqctx->idctx, CMS_SIGN_CLIENT,
+                                            (unsigned char *)coded_auth_pack->data, coded_auth_pack->length,
+                                            &req->signedAuthPack.data, &req->signedAuthPack.length);
+            else         retval = cms_signeddata_create(context, plgctx->cryptoctx,
+                                                        reqctx->cryptoctx, reqctx->idctx, CMS_SIGN_CLIENT, 1,
+                                                        (unsigned char *)coded_auth_pack->data, coded_auth_pack->length,
+                                                        &req->signedAuthPack.data, &req->signedAuthPack.length);
 #ifdef DEBUG_ASN1
         print_buffer_bin((unsigned char *)req->signedAuthPack.data,
                          req->signedAuthPack.length,
@@ -677,7 +686,7 @@
                                             reqctx->opts->require_crl_checking,
                                             kdc_reply->u.dh_Info.dhSignedData.data,
                                             kdc_reply->u.dh_Info.dhSignedData.length,
-                                            &dh_data.data, &dh_data.length, NULL, NULL)) != 0) {
+                                            &dh_data.data, &dh_data.length, NULL, NULL, NULL)) != 0) {
             pkiDebug("failed to verify pkcs7 signed data\n");
             goto cleanup;
         }

Modified: branches/anonymous/src/plugins/preauth/pkinit/pkinit_crypto.h
===================================================================
--- branches/anonymous/src/plugins/preauth/pkinit/pkinit_crypto.h	2009-12-23 21:09:50 UTC (rev 23492)
+++ branches/anonymous/src/plugins/preauth/pkinit/pkinit_crypto.h	2009-12-23 21:09:53 UTC (rev 23493)
@@ -181,8 +181,9 @@
 		    receives required authorization data that
 		    contains the verified certificate chain
 		    (only used by the KDC) */
-	unsigned int *authz_data_len);			/* OUT
-		    receives length of authz_data */
+	 unsigned int *authz_data_len,			/* OUT
+							   receives length of authz_data */
+	 int *is_signed /*out: is message signed*/);
 
 /*
  * this function creates a CMS message where eContentType is EnvelopedData

Modified: branches/anonymous/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
===================================================================
--- branches/anonymous/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c	2009-12-23 21:09:50 UTC (rev 23492)
+++ branches/anonymous/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c	2009-12-23 21:09:53 UTC (rev 23493)
@@ -1120,8 +1120,9 @@
                       unsigned char **data,
                       unsigned int *data_len,
                       unsigned char **authz_data,
-                      unsigned int *authz_data_len)
-{
+                      unsigned int *authz_data_len,
+                      int *is_signed)
+    {
     krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
     PKCS7 *p7 = NULL;
     BIO *out = NULL;
@@ -1146,7 +1147,8 @@
     print_buffer_bin(signed_data, signed_data_len,
                      "/tmp/client_received_pkcs7_signeddata");
 #endif
-
+    if (is_signed)
+        *is_signed = 1;
     /* Do this early enough to create the shadow OID for pkcs7-data if needed */
     oid = pkinit_pkcs7type2oid(plgctx, cms_msg_type);
     if (oid == NULL)
@@ -1162,12 +1164,32 @@
         goto cleanup;
     }
 
-    /* verify that the received message is PKCS7 SignedData message */
-    if (OBJ_obj2nid(p7->type) != NID_pkcs7_signed) {
-        pkiDebug("Expected id-signedData PKCS7 msg (received type = %d)\n",
-                 OBJ_obj2nid(p7->type));
-        krb5_set_error_message(context, retval, "wrong oid\n");
-        goto cleanup;
+/*Handle the case in pkinit anonymous where  we get unsigned data.*/
+    if (is_signed && !OBJ_cmp( p7->type, oid)) {
+        unsigned char *d;
+        *is_signed = 0;
+        if (p7->d.other->type != V_ASN1_OCTET_STRING) {
+            retval = KRB5KDC_ERR_PREAUTH_FAILED;
+            krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED, "Invalid pkinit packet: octet string expected");
+            goto cleanup;
+        }
+        *data_len = ASN1_STRING_length(p7->d.other->value.octet_string);
+        d = malloc(*data_len);
+        if (d == NULL) {
+            retval = ENOMEM;
+            goto cleanup;
+        }
+        memcpy(d, ASN1_STRING_data(p7->d.other->value.octet_string),
+               *data_len);
+        *data = d;
+        goto out;
+    } else     /* verify that the received message is PKCS7 SignedData message */
+        if (OBJ_obj2nid(p7->type) != NID_pkcs7_signed) {
+
+            pkiDebug("Expected id-signedData PKCS7 msg (received type = %d)\n",
+                     OBJ_obj2nid(p7->type));
+            krb5_set_error_message(context, retval, "wrong oid\n");
+            goto cleanup;
     }
 
     /* setup to verify X509 certificate used to sign PKCS7 message */
@@ -1370,7 +1392,6 @@
     for (size = 0;;) {
         int remain;
         retval = ENOMEM;
-
         if ((*data = realloc(*data, size + 1024 * 10)) == NULL)
             goto cleanup;
         remain = BIO_read(out, &((*data)[size]), 1024 * 10);
@@ -1703,7 +1724,7 @@
                                    id_cryptoctx, msg_type,
                                    require_crl_checking,
                                    vfy_buf, vfy_buf_len,
-                                   data, data_len, NULL, NULL);
+                                   data, data_len, NULL, NULL, NULL);
 
     if (!retval)
         pkiDebug("PKCS7 Verification Success\n");

Modified: branches/anonymous/src/plugins/preauth/pkinit/pkinit_srv.c
===================================================================
--- branches/anonymous/src/plugins/preauth/pkinit/pkinit_srv.c	2009-12-23 21:09:50 UTC (rev 23492)
+++ branches/anonymous/src/plugins/preauth/pkinit/pkinit_srv.c	2009-12-23 21:09:53 UTC (rev 23493)
@@ -314,6 +314,7 @@
     krb5_authdata **my_authz_data = NULL, *pkinit_authz_data = NULL;
     krb5_kdc_req *tmp_as_req = NULL;
     krb5_data k5data;
+    int is_signed = 1;
     krb5_keyblock *armor_key;
 
     pkiDebug("pkinit_verify_padata: entered!\n");
@@ -367,7 +368,7 @@
                                        plgctx->opts->require_crl_checking,
                                        reqp->signedAuthPack.data, reqp->signedAuthPack.length,
                                        &authp_data.data, &authp_data.length, &krb5_authz.data,
-                                       &krb5_authz.length);
+                                       &krb5_authz.length, &is_signed);
         break;
     case KRB5_PADATA_PK_AS_REP_OLD:
     case KRB5_PADATA_PK_AS_REQ_OLD:
@@ -389,7 +390,7 @@
                                        plgctx->opts->require_crl_checking,
                                        reqp9->signedAuthPack.data, reqp9->signedAuthPack.length,
                                        &authp_data.data, &authp_data.length, &krb5_authz.data,
-                                       &krb5_authz.length);
+                                       &krb5_authz.length, NULL);
         break;
     default:
         pkiDebug("unrecognized pa_type = %d\n", data->pa_type);
@@ -400,28 +401,35 @@
         pkiDebug("pkcs7_signeddata_verify failed\n");
         goto cleanup;
     }
+    if (is_signed) {
 
-    retval = verify_client_san(context, plgctx, reqctx, request->client,
-                               &valid_san);
-    if (retval)
-        goto cleanup;
-    if (!valid_san) {
-        pkiDebug("%s: did not find an acceptable SAN in user certificate\n",
-                 __FUNCTION__);
-        retval = KRB5KDC_ERR_CLIENT_NAME_MISMATCH;
-        goto cleanup;
-    }
-    retval = verify_client_eku(context, plgctx, reqctx, &valid_eku);
-    if (retval)
-        goto cleanup;
+        retval = verify_client_san(context, plgctx, reqctx, request->client,
+                                   &valid_san);
+        if (retval)
+            goto cleanup;
+        if (!valid_san) {
+            pkiDebug("%s: did not find an acceptable SAN in user certificate\n",
+                     __FUNCTION__);
+            retval = KRB5KDC_ERR_CLIENT_NAME_MISMATCH;
+            goto cleanup;
+        }
+        retval = verify_client_eku(context, plgctx, reqctx, &valid_eku);
+        if (retval)
+            goto cleanup;
 
-    if (!valid_eku) {
-        pkiDebug("%s: did not find an acceptable EKU in user certificate\n",
-                 __FUNCTION__);
-        retval = KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE;
-        goto cleanup;
+        if (!valid_eku) {
+            pkiDebug("%s: did not find an acceptable EKU in user certificate\n",
+                     __FUNCTION__);
+            retval = KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE;
+            goto cleanup;
+        }
+    } else { /*!is_signed*/
+        if (!krb5_principal_compare( context, request->client, krb5_anonymous_principal())) {
+            retval = KRB5KDC_ERR_PREAUTH_FAILED;
+            krb5_set_error_message(context, retval, "Pkinit request not signed, but client not anonymous.");
+            goto cleanup;
+        }
     }
-
 #ifdef DEBUG_ASN1
     print_buffer_bin(authp_data.data, authp_data.length, "/tmp/kdc_auth_pack");
 #endif
@@ -446,6 +454,11 @@
                 pkiDebug("bad dh parameters\n");
                 goto cleanup;
             }
+        } else if (!is_signed) {
+            /*Anonymous pkinit requires DH*/
+            retval = KRB5KDC_ERR_PREAUTH_FAILED;
+            krb5_set_error_message(context, retval, "Anonymous pkinit without DH public value not supported.");
+            goto cleanup;
         }
         /*
          * The KDC may have modified the request after decoding it.




More information about the cvs-krb5 mailing list