Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/crypto/dist/ipsec-tools pkcs7 support



details:   https://anonhg.NetBSD.org/src/rev/921b19d1b53f
branches:  trunk
changeset: 582956:921b19d1b53f
user:      manu <manu%NetBSD.org@localhost>
date:      Tue Jul 12 14:12:20 2005 +0000

description:
pkcs7 support

diffstat:

 crypto/dist/ipsec-tools/ChangeLog           |    5 +
 crypto/dist/ipsec-tools/src/racoon/oakley.c |  227 +++++++++++++++++++++------
 2 files changed, 180 insertions(+), 52 deletions(-)

diffs (275 lines):

diff -r e7329ed92f32 -r 921b19d1b53f crypto/dist/ipsec-tools/ChangeLog
--- a/crypto/dist/ipsec-tools/ChangeLog Tue Jul 12 13:41:34 2005 +0000
+++ b/crypto/dist/ipsec-tools/ChangeLog Tue Jul 12 14:12:20 2005 +0000
@@ -1,3 +1,8 @@
+2005-07-01  Emmanuel Dreyfus  <manu%netbsd.org@localhost>
+
+       From Uri <urimobile%optonline.net@localhost>
+       * src/racoon/oakley.c: pkcs7 support
+
 2005-06-22  Emmanuel Dreyfus  <manu%netbsd.org@localhost>
 
        From Ludo Stellingwerff <ludo%protactive.nl@localhost>:
diff -r e7329ed92f32 -r 921b19d1b53f crypto/dist/ipsec-tools/src/racoon/oakley.c
--- a/crypto/dist/ipsec-tools/src/racoon/oakley.c       Tue Jul 12 13:41:34 2005 +0000
+++ b/crypto/dist/ipsec-tools/src/racoon/oakley.c       Tue Jul 12 14:12:20 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: oakley.c,v 1.1.1.3 2005/03/14 08:14:31 manu Exp $      */
+/*     $NetBSD: oakley.c,v 1.2 2005/07/12 14:12:20 manu Exp $  */
 
 /* Id: oakley.c,v 1.17.2.1 2005/03/01 09:51:48 vanhu Exp */
 
@@ -38,6 +38,9 @@
 #include <sys/socket.h>        /* XXX for subjectaltname */
 #include <netinet/in.h>        /* XXX for subjectaltname */
 
+#include <openssl/pkcs7.h>
+#include <openssl/x509.h>
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -122,6 +125,7 @@
 static int oakley_check_certid __P((struct ph1handle *iph1));
 static int check_typeofcertname __P((int, int));
 static cert_t *save_certbuf __P((struct isakmp_gen *));
+static cert_t *save_certx509 __P((X509 *));
 static int oakley_padlen __P((int, int));
 
 int
@@ -2009,58 +2013,144 @@
                return 0;
        }
 
-       *c = save_certbuf(gen);
-       if (!*c) {
-               plog(LLV_ERROR, LOCATION, NULL,
-                       "Failed to get CERT buffer.\n");
-               return -1;
-       }
-
-       switch ((*c)->type) {
-       case ISAKMP_CERT_DNS:
-               plog(LLV_WARNING, LOCATION, NULL,
-                       "CERT payload is unnecessary in DNSSEC. "
-                       "ignore it.\n");
-               return 0;
-       case ISAKMP_CERT_PKCS7:
-       case ISAKMP_CERT_PGP:
-       case ISAKMP_CERT_X509SIGN:
-       case ISAKMP_CERT_KERBEROS:
-       case ISAKMP_CERT_SPKI:
-               /* Ignore cert if it doesn't match identity
-                * XXX If verify cert is disabled, we still just take
-                * the first certificate....
+        if (type == ISAKMP_CERT_PKCS7) {
+                 PKCS7 *p7;
+                 u_char *bp;
+                 int i;
+
+                 /* Skip the header */
+                 bp = (u_char *)(gen + 1);
+                 /* And the first byte is the certificate type, 
+                   we know that already
                 */
-               if(iph1->rmconf->verify_cert &&
-                  oakley_check_certid(iph1)){
-                       plog(LLV_DEBUG, LOCATION, NULL,
-                                "Discarding CERT: does not match ID.\n");
-                       oakley_delcert((*c));
-                       *c = NULL;
-                       return 0;
-               }
-               plog(LLV_DEBUG, LOCATION, NULL, "CERT saved:\n");
-               plogdump(LLV_DEBUG, (*c)->cert.v, (*c)->cert.l);
-               {
-                       char *p = eay_get_x509text(&(*c)->cert);
-                       plog(LLV_DEBUG, LOCATION, NULL, "%s", p ? p : "\n");
-                       racoon_free(p);
-               }
-               break;
-       case ISAKMP_CERT_CRL:
-               plog(LLV_DEBUG, LOCATION, NULL, "CRL saved:\n");
-               plogdump(LLV_DEBUG, (*c)->cert.v, (*c)->cert.l);
-               break;
-       case ISAKMP_CERT_X509KE:
-       case ISAKMP_CERT_X509ATTR:
-       case ISAKMP_CERT_ARL:
-       default:
-               /* XXX */
-               oakley_delcert((*c));
-               *c = NULL;
-               return 0;
-       }
-
+                 bp++;
+                 p7 = d2i_PKCS7(NULL, &bp, ntohs(gen->len) - sizeof(*gen) - 1);
+                
+                 if (!p7) {
+                  plog(LLV_ERROR, LOCATION, NULL,
+                       "Failed to parse PKCS#7 CERT.\n");
+                  return -1;
+                 }
+
+                 /* Copied this from the openssl pkcs7 application;
+                  * there"s little by way of documentation for any of
+                  * it. I can only presume it"s correct.
+                  */
+                STACK_OF(X509) *certs=NULL;
+                
+                i = OBJ_obj2nid(p7->type);
+                switch (i) {
+                case NID_pkcs7_signed:
+                  certs=p7->d.sign->cert;
+                  break;
+                 case NID_pkcs7_signedAndEnveloped:
+                  certs=p7->d.signed_and_enveloped->cert;
+                  break;
+                 default:
+                         break;
+                 }
+
+                 if (!certs) {
+                         plog(LLV_ERROR, LOCATION, NULL,
+                              "CERT PKCS#7 bundle contains no certs.\n");
+                         PKCS7_free(p7);
+                         return -1;
+                 }
+
+                 for (i = 0; i < sk_X509_num(certs); i++) {
+                         int len;
+                         u_char *bp;
+                         X509 *cert = sk_X509_value(certs,i);
+
+                         plog(LLV_DEBUG, LOCATION, NULL, 
+                             "Trying PKCS#7 cert %d.\n", i);
+
+                         /* We"ll just try each cert in turn */
+                         *c = save_certx509(cert);
+
+                         if (!*c) {
+                                 plog(LLV_ERROR, LOCATION, NULL,
+                                      "Failed to get CERT buffer.\n");
+                                 continue;
+                         }
+
+                         /* Ignore cert if it doesn't match identity
+                          * XXX If verify cert is disabled, we still just take
+                          * the first certificate....
+                          */
+                         if(iph1->rmconf->verify_cert &&
+                            oakley_check_certid(iph1)){
+                                 plog(LLV_DEBUG, LOCATION, NULL,
+                                      "Discarding CERT: does not match ID.\n");
+                                 oakley_delcert((*c));
+                                 *c = NULL;
+                                 continue;
+                         }
+                         plog(LLV_DEBUG, LOCATION, NULL, "CERT saved:\n");
+                         plogdump(LLV_DEBUG, (*c)->cert.v, (*c)->cert.l);
+                         {
+                                 char *p = eay_get_x509text(&(*c)->cert);
+                                 plog(LLV_DEBUG, LOCATION, NULL, "%s", 
+                                     p ? p : "\n");
+                                 racoon_free(p);
+                         }
+                         break;
+                 }
+
+                 PKCS7_free(p7);
+         } else {
+          *c = save_certbuf(gen);
+          if (!*c) {
+            plog(LLV_ERROR, LOCATION, NULL,
+                 "Failed to get CERT buffer.\n");
+            return -1;
+          }
+          
+          switch ((*c)->type) {
+          case ISAKMP_CERT_DNS:
+            plog(LLV_WARNING, LOCATION, NULL,
+                 "CERT payload is unnecessary in DNSSEC. "
+                 "ignore it.\n");
+            return 0;
+          case ISAKMP_CERT_PGP:
+          case ISAKMP_CERT_X509SIGN:
+          case ISAKMP_CERT_KERBEROS:
+          case ISAKMP_CERT_SPKI:
+            /* Ignore cert if it doesn't match identity
+             * XXX If verify cert is disabled, we still just take
+             * the first certificate....
+             */
+            if(iph1->rmconf->verify_cert &&
+               oakley_check_certid(iph1)){
+              plog(LLV_DEBUG, LOCATION, NULL,
+                   "Discarding CERT: does not match ID.\n");
+              oakley_delcert((*c));
+              *c = NULL;
+              return 0;
+            }
+            plog(LLV_DEBUG, LOCATION, NULL, "CERT saved:\n");
+            plogdump(LLV_DEBUG, (*c)->cert.v, (*c)->cert.l);
+            {
+              char *p = eay_get_x509text(&(*c)->cert);
+              plog(LLV_DEBUG, LOCATION, NULL, "%s", p ? p : "\n");
+              racoon_free(p);
+            }
+            break;
+          case ISAKMP_CERT_CRL:
+            plog(LLV_DEBUG, LOCATION, NULL, "CRL saved:\n");
+            plogdump(LLV_DEBUG, (*c)->cert.v, (*c)->cert.l);
+            break;
+          case ISAKMP_CERT_X509KE:
+          case ISAKMP_CERT_X509ATTR:
+          case ISAKMP_CERT_ARL:
+          default:
+            /* XXX */
+            oakley_delcert((*c));
+            *c = NULL;
+            return 0;
+          }
+        }
+       
        return 0;
 }
 
@@ -2144,6 +2234,39 @@
        return new;
 }
 
+static cert_t *
+save_certx509(cert)
+       X509 *cert;
+{
+       cert_t *new;
+        int len;
+        u_char *bp;
+
+       new = oakley_newcert();
+       if (!new) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "Failed to get CERT buffer.\n");
+               return NULL;
+       }
+
+        len = i2d_X509(cert, NULL);
+       new->pl = vmalloc(len);
+       if (new->pl == NULL) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "Failed to copy CERT from packet.\n");
+               oakley_delcert(new);
+               new = NULL;
+               return NULL;
+       }
+        bp = new->pl->v;
+        len = i2d_X509(cert, &bp);
+       new->type = ISAKMP_CERT_X509SIGN;
+       new->cert.v = new->pl->v;
+       new->cert.l = new->pl->l;
+
+       return new;
+}
+
 /*
  * get my CR.
  * NOTE: No Certificate Authority field is included to CR payload at the



Home | Main Index | Thread Index | Old Index