]> git.saurik.com Git - apple/ipsec.git/commitdiff
ipsec-93.6.tar.gz mac-os-x-1063 v93.6
authorApple <opensource@apple.com>
Mon, 29 Mar 2010 18:40:32 +0000 (18:40 +0000)
committerApple <opensource@apple.com>
Mon, 29 Mar 2010 18:40:32 +0000 (18:40 +0000)
12 files changed:
ipsec-tools/Common/ipsecMessageTracer.h
ipsec-tools/racoon/crypto_cssm.c
ipsec-tools/racoon/crypto_cssm.h
ipsec-tools/racoon/ike_session.c
ipsec-tools/racoon/ike_session.h
ipsec-tools/racoon/isakmp.c
ipsec-tools/racoon/isakmp_inf.c
ipsec-tools/racoon/isakmp_var.h
ipsec-tools/racoon/oakley.c
ipsec-tools/racoon/oakley.h
ipsec-tools/racoon/pfkey_racoon.c
ipsec-tools/racoon/vpn_control.h

index 14bafba960533d6b630d5081086332e86985acc0..9a3f50a130288db80e7c29f85500593afa5ae913 100644 (file)
 #define PLAINIPSEC_PHASE_DOMAIN                                                 CONSTSTR("com.apple.Networking.ipsec.phasestats.plain")
 #define PLAINIPSECDOMAIN                                                        CONSTSTR("com.apple.Networking.ipsec.main")
 
+#if TARGET_OS_EMBEDDED
+
+#define IPSECCONFIGTRACEREVENT(config, eventCode, message, failure_reason)             
+
+#define IPSECPOLICYTRACEREVENT(policy, eventCode, message, failure_reason)             
+
+#define IPSECSESSIONTRACERSTART(session)                                                                               
+#define IPSECSESSIONTRACEREVENT(session, eventCode, message, failure_reason)   
+#define IPSECSESSIONTRACERSTOP(session, is_failure, reason)                                            
+#define IPSECSESSIONTRACERESTABLISHED(session)                                  
+
+#else
+
 #define IPSECCONFIGTRACEREVENT(config, eventCode, message, failure_reason)             ipsecConfigTracerEvent(config, eventCode, message, failure_reason)
 
 #define IPSECPOLICYTRACEREVENT(policy, eventCode, message, failure_reason)             ipsecPolicyTracerEvent(policy, eventCode, message, failure_reason)
@@ -48,6 +61,8 @@
 #define IPSECSESSIONTRACERSTOP(session, is_failure, reason)                                            ipsecSessionTracerStop(session, is_failure, reason)
 #define IPSECSESSIONTRACERESTABLISHED(session)                                  ipsecSessionTracerLogEstablished(session)
 
+#endif
+
 static inline double get_percentage (double numerator, double denominator)
 {
     if (numerator >= denominator || denominator == 0) {
index e5b35d6bdebb914f89e17296223461a7453d05f7..e47aa6dde2d262e8a304e8915cf903031cd8d820 100644 (file)
@@ -36,6 +36,9 @@
 #include <TargetConditionals.h>
 #if TARGET_OS_EMBEDDED
 #include <Security/SecItem.h>
+#include <Security/SecTrustPriv.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecCertificatePriv.h>
 #else
 #include <Security/SecBase.h>
 #include <Security/SecIdentityPriv.h>
@@ -55,6 +58,7 @@
 #include "plog.h"
 #include "debug.h"
 #include "misc.h"
+#include "oakley.h"
 
 
 #include "crypto_cssm.h"
@@ -70,7 +74,7 @@ static OSStatus CopySystemKeychain(SecKeychainRef *keychainRef);
 /*
  * Verify cert using security framework
  */
-int crypto_cssm_check_x509cert(vchar_t *cert, CFStringRef hostname)
+int crypto_cssm_check_x509cert(vchar_t *cert, CFStringRef hostname, cert_status_t certStatus)
 {
        OSStatus                        status;
        SecCertificateRef       certRef = NULL;
@@ -110,22 +114,13 @@ int crypto_cssm_check_x509cert(vchar_t *cert, CFStringRef hostname)
        }
 
        if (hostname) {
-               policyRef = SecPolicyCreateSSL(FALSE, hostname);
+               policyRef = SecPolicyCreateIPSec(FALSE, hostname);
                if (policyRef == NULL) {
                        plog(LLV_ERROR, LOCATION, NULL, 
                                "unable to create a SSL policyRef.\n");
                        status = -1;
                        goto end;
                }
-       } else
-         {
-               policyRef = SecPolicyCreateBasicX509();
-               if (policyRef == NULL) {
-                       plog(LLV_ERROR, LOCATION, NULL, 
-                               "unable to create a Basic X509 policyRef.\n");
-                       status = -1;
-                       goto end;
-               }
        }
        
 #endif
@@ -144,7 +139,11 @@ end:
                plog(LLV_ERROR, LOCATION, NULL, 
                        "error %d %s.\n", status, GetSecurityErrorString(status));
                status = -1;
-       }               
+       } else if (certStatus) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                        "certificate failed date verification: %d.\n", certStatus);
+               status = -1;
+       }
        return status;
 
 }
@@ -350,7 +349,8 @@ end:
 /*
  * Retrieve a cert from the keychain
  */
-vchar_t* crypto_cssm_get_x509cert(CFDataRef persistentCertRef)
+vchar_t* crypto_cssm_get_x509cert(CFDataRef persistentCertRef,
+                                  cert_status_t *certStatus)
 {
 
        OSStatus                                status;
@@ -408,6 +408,10 @@ vchar_t* crypto_cssm_get_x509cert(CFDataRef persistentCertRef)
        // data must be copied to be returned
        memcpy(cert->v, cssmData.Data, cssmData.Length);        
        
+       // verify expiry or missing fields
+       if (certStatus) {
+               *certStatus = CERT_STATUS_OK;
+       }
 #else
                
        CFDictionaryRef         persistFind = NULL;
@@ -415,6 +419,21 @@ vchar_t* crypto_cssm_get_x509cert(CFDataRef persistentCertRef)
        const void                      *values_persist[] = { kCFBooleanTrue, persistentCertRef };
        size_t                          dataLen;
        CFDataRef                       certData = NULL;
+       CFAbsoluteTime          timeNow = 0;
+       CFAbsoluteTime          notvalidbeforedate = 0;
+       CFAbsoluteTime          notvalidafterdate = 0;
+       CFDateRef                       nowcfdatedata = NULL;
+       CFDateRef                       notvalidbeforedatedata = NULL;
+       CFDateRef                       notvalidafterdatedata = NULL;
+       CFArrayRef                      certProparray = NULL;
+       CFRange                         range;
+       CFDictionaryRef         *values = NULL;
+       CFDictionaryRef         propDict = NULL;
+       const void                      *datevalue = NULL;
+       const void                      *labelvalue = NULL;
+       CFGregorianDate         gregoriandate;
+       int                                     count;
+       int                                     i;
        
        /* find identity by persistent ref */
        persistFind = CFDictionaryCreate(NULL, keys_persist, values_persist,
@@ -444,6 +463,68 @@ vchar_t* crypto_cssm_get_x509cert(CFDataRef persistentCertRef)
        
        CFDataGetBytes(certData, CFRangeMake(0, dataLen), cert->v); 
                                
+       // verify expiry or missing fields
+       if (certStatus) {
+               
+               *certStatus = CERT_STATUS_OK;
+               
+               if ((certProparray = SecCertificateCopyProperties(certificateRef))){
+                       if ((count = CFArrayGetCount( certProparray ))){
+                               range.location = 0;
+                               range.length = count;
+                               if ( (values = CFAllocatorAllocate(NULL, count * sizeof(CFDictionaryRef), 0))){
+                                       CFArrayGetValues(certProparray, range, (const void **)values);
+                                       for( i = 0; i < count; i++)
+                                       {  
+                                               if ((propDict = values[i])){
+                                                       if ( CFDictionaryContainsValue(propDict, kSecPropertyTypeDate) ){
+                                                               if ( CFDictionaryGetValueIfPresent(propDict, kSecPropertyKeyValue, (const void**)&datevalue)){
+                                                                       /* get kSecPropertyKeyLabel */
+                                                                       if ( (datevalue) && (CFDictionaryGetValueIfPresent(propDict, kSecPropertyKeyLabel, (const void**)&labelvalue))){
+                                                                               if ( (labelvalue) && (CFStringCompare( (CFStringRef)labelvalue, CFSTR("Not Valid Before"), 0) == kCFCompareEqualTo)){
+                                                                                       if ( notvalidbeforedate = CFDateGetAbsoluteTime(datevalue))
+                                                                                               notvalidbeforedatedata = CFDateCreate(NULL, notvalidbeforedate);
+                                                                               }else if ((labelvalue) && (CFStringCompare( (CFStringRef)labelvalue, CFSTR("Not Valid After"), 0 ) == kCFCompareEqualTo)){
+                                                                                       if ( notvalidafterdate = CFDateGetAbsoluteTime(datevalue))
+                                                                                               notvalidafterdatedata = CFDateCreate(NULL, notvalidafterdate);
+                                                                               }
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                               
+                                       }       
+                               }
+                       }
+               }
+               
+               if ( (timeNow = CFAbsoluteTimeGetCurrent()) && (nowcfdatedata = CFDateCreate( NULL, timeNow))){
+                       if ( notvalidbeforedatedata ){
+                               gregoriandate = CFAbsoluteTimeGetGregorianDate(notvalidbeforedate, NULL);
+                               plog(LLV_DEBUG, LOCATION, NULL, 
+                                        "cert not valid before yr %d, mon %d, days %d, hours %d, min %d\n", gregoriandate.year, gregoriandate.month, gregoriandate.day, gregoriandate.hour, gregoriandate.minute);
+                               gregoriandate = CFAbsoluteTimeGetGregorianDate(notvalidafterdate, NULL);
+                               plog(LLV_DEBUG, LOCATION, NULL, 
+                                        "cert not valid after yr %d, mon %d, days %d, hours %d, min %d\n", gregoriandate.year, gregoriandate.month, gregoriandate.day, gregoriandate.hour, gregoriandate.minute);
+                               if ( CFDateCompare( nowcfdatedata, notvalidbeforedatedata, NULL ) == kCFCompareLessThan){
+                                       plog(LLV_ERROR, LOCATION, NULL, 
+                                                "current time before valid time\n");
+                                       *certStatus = CERT_STATUS_PREMATURE;
+                               }
+                               else if (notvalidafterdatedata && (CFDateCompare( nowcfdatedata, notvalidafterdatedata, NULL ) == kCFCompareGreaterThan)){
+                                       plog(LLV_ERROR, LOCATION, NULL, 
+                                                "current time after valid time\n");
+                                       *certStatus = CERT_STATUS_EXPIRED;
+                               }else {
+                                       plog(LLV_INFO, LOCATION, NULL, "certificate expiration date OK\n");
+                                       *certStatus = CERT_STATUS_OK;
+                               }
+
+                       }
+
+               }
+       }
+
 #endif
                
 end:
@@ -457,6 +538,16 @@ end:
        if (keychainRef)
                CFRelease(keychainRef);
 #else
+       if (notvalidbeforedatedata)
+               CFRelease(notvalidbeforedatedata);
+       if (notvalidafterdatedata)
+               CFRelease(notvalidafterdatedata);
+       if (certProparray)
+               CFRelease(certProparray);
+       if (values)
+               CFAllocatorDeallocate(NULL, values);
+       if (nowcfdatedata)
+               CFRelease(nowcfdatedata);
        if (persistFind)
                CFRelease(persistFind);
        if (certData)
@@ -509,6 +600,13 @@ static OSStatus EvaluateCert(SecCertificateRef cert, CFTypeRef policyRef)
        OSStatus                                        status;
        SecTrustRef                                     trustRef = 0;
        SecTrustResultType                      evalResult;
+
+#if TARGET_OS_EMBEDDED 
+       CFArrayRef                                      errorStrings;
+#else
+       CSSM_TP_APPLE_EVIDENCE_INFO                     *statusChain;
+       CFArrayRef                                      certChain;
+#endif
        
        SecCertificateRef                       evalCertArray[1] = { cert };
        
@@ -524,14 +622,89 @@ static OSStatus EvaluateCert(SecCertificateRef cert, CFTypeRef policyRef)
        status = SecTrustCreateWithCertificates(cfCertRef, policyRef, &trustRef);
        if (status != noErr)
                goto end;
-               
+
        status = SecTrustEvaluate(trustRef, &evalResult);
        if (status != noErr)
                goto end;
        
        if (evalResult != kSecTrustResultProceed && evalResult != kSecTrustResultUnspecified) {
-               plog(LLV_ERROR, LOCATION, NULL, 
-                       "error evaluating certificate.\n");
+               plog(LLV_ERROR, LOCATION, NULL, "Error evaluating certificate.\n");
+
+               switch (evalResult) {
+                       case kSecTrustResultInvalid:
+                               plog(LLV_DEBUG, LOCATION, NULL, "eval result = kSecTrustResultInvalid.\n");
+                               break;
+                       case kSecTrustResultProceed:
+                               plog(LLV_DEBUG, LOCATION, NULL, "eval result = kSecTrustResultProceed.\n");
+                               break;
+                       case kSecTrustResultConfirm:
+                               plog(LLV_DEBUG, LOCATION, NULL, "eval result = kSecTrustResultConfirm.\n");
+                               break;
+                       case kSecTrustResultDeny:
+                               plog(LLV_DEBUG, LOCATION, NULL, "eval result = kSecTrustResultDeny.\n");
+                               break;
+                       case kSecTrustResultUnspecified:
+                               plog(LLV_DEBUG, LOCATION, NULL, "eval result = kSecTrustResultUnspecified.\n");
+                               break;
+                       case kSecTrustResultRecoverableTrustFailure:
+                               plog(LLV_DEBUG, LOCATION, NULL, "eval result = kSecTrustResultRecoverableTrustFailure.\n");
+                               break;
+                       case kSecTrustResultFatalTrustFailure:
+                               plog(LLV_DEBUG, LOCATION, NULL, "eval result = kSecTrustResultFatalTrustFailure.\n");
+                               break;
+                       case kSecTrustResultOtherError:
+                               plog(LLV_DEBUG, LOCATION, NULL, "eval result = kSecTrustResultOtherError.\n");
+                               break;
+                       default:
+                               plog(LLV_DEBUG, LOCATION, NULL, "eval result unknown: value = %d.\n", (int)evalResult);
+                               break;
+               }
+
+
+#if TARGET_OS_EMBEDDED                 
+               errorStrings =  SecTrustCopyProperties(trustRef);
+               if (errorStrings) {
+                       
+                       CFDictionaryRef dict;
+                       CFStringRef val;
+                       const char *str;        
+                       CFIndex count, maxcount = CFArrayGetCount(errorStrings);
+               
+                       plog(LLV_ERROR, LOCATION, NULL, "---------------Returned error strings: ---------------.\n");
+                       for (count = 0; count < maxcount; count++) {
+                               dict = CFArrayGetValueAtIndex(errorStrings, count);
+                               if (dict && (CFGetTypeID(dict) == CFDictionaryGetTypeID())) {
+                                       val = CFDictionaryGetValue(dict, kSecPropertyKeyType);
+                                       if (val && (CFGetTypeID(val) == CFStringGetTypeID())) {
+                                               str = CFStringGetCStringPtr(val, kCFStringEncodingMacRoman);    
+                                               if (str)                
+                                                       plog(LLV_ERROR, LOCATION, NULL, "type = %s.\n", str);
+                                       }
+                                       val = CFDictionaryGetValue(dict, kSecPropertyKeyValue);
+                                       if (val && (CFGetTypeID(val) == CFStringGetTypeID())) {
+                                               str = CFStringGetCStringPtr(val, kCFStringEncodingMacRoman);    
+                                               if (str)                
+                                                       plog(LLV_ERROR, LOCATION, NULL, "value = %s.\n", str);
+                                       }
+                               }
+                       }
+                       plog(LLV_ERROR, LOCATION, NULL, "-----------------------------------------------------.\n");                    
+                       CFRelease(errorStrings);
+               }
+               
+#else
+               SecTrustGetResult(trustRef, &evalResult, &certChain, &statusChain);
+               plog(LLV_ERROR, LOCATION, NULL, "Cert status bits = 0x%x.\n", statusChain->StatusBits);
+               plog(LLV_ERROR, LOCATION, NULL, "Cert status NumStatusCodes = 0x%x.\n", statusChain->NumStatusCodes);
+               {
+                       int i;
+                       for (i = 0; i < statusChain->NumStatusCodes; i++)               
+                               plog(LLV_ERROR, LOCATION, NULL, "Cert status code i = 0x%x  %d.\n", *(statusChain->StatusCodes + i), *(statusChain->StatusCodes + i));
+               }
+               plog(LLV_ERROR, LOCATION, NULL, "Cert status Index = %d.\n", statusChain->Index);
+               CFRelease(certChain);
+#endif
+               
                status = -1;
        }
                        
index e7c94c36be5d9166fb22c6db1d9ff1c6adf6b1f3..d0562bf9564937c51928a60b4c692912c3213b73 100644 (file)
@@ -33,9 +33,9 @@
 #include <CoreFoundation/CoreFoundation.h>
 
 
-extern int crypto_cssm_check_x509cert(vchar_t *cert, CFStringRef hostname);
+extern int crypto_cssm_check_x509cert(vchar_t *cert, CFStringRef hostname, cert_status_t certStatus);
 extern vchar_t* crypto_cssm_getsign(CFDataRef persistentCertRef, vchar_t* hash);
-extern vchar_t* crypto_cssm_get_x509cert(CFDataRef persistentCertRef);
+extern vchar_t* crypto_cssm_get_x509cert(CFDataRef persistentCertRef, cert_status_t *certStatus);
 
 
 #endif /* __CRYPTO_CSSM_H__ */
index 3bb62d7cc449df4537629d6cf7e152720fc92530..ffc1516d50a03c223f20029b51e7e5f563591121 100644 (file)
@@ -1207,6 +1207,8 @@ ike_session_update_traffic_idle_status (ike_session_t *session,
             session->i_sent_data_sc_idle = 1;
         }
     }
+       if (!idle)
+               session->last_time_data_sc_detected = time(NULL);                                                                               
 
        ike_session_monitor_idle(session);
 }
@@ -1465,4 +1467,58 @@ ike_session_get_sainfo_r (struct ph2handle *iph2)
                }
        }
        return -1;
-}
\ No newline at end of file
+}
+
+int
+ike_session_drop_rekey (ike_session_t *session)
+{
+       if (session) {
+               // drop if btmm session is idle) {
+               if (session->is_btmm_ipsec &&
+                       session->last_time_data_sc_detected &&
+                       session->traffic_monitor.interv_mon &&
+                       session->traffic_monitor.interv_idle) {
+                       time_t now = time(NULL);
+
+                       if ((now - session->last_time_data_sc_detected) > (session->traffic_monitor.interv_mon << 1)) {
+                               plog(LLV_DEBUG2, LOCATION, NULL, "session is idle: drop rekey.\n");
+                               return 1;
+                       }
+               }
+       }
+       return 0;
+}
+
+void
+ike_session_ph2_retransmits (struct ph2handle *iph2)
+{
+       int num_retransmits;
+
+       if (!iph2->is_dying &&
+               iph2->is_rekey &&
+               iph2->ph1 &&
+               iph2->ph1->sce_rekey && !iph2->ph1->sce_rekey->dead &&
+               iph2->parent_session &&
+               !iph2->parent_session->is_cisco_ipsec && /* not for Cisco */
+               iph2->parent_session->is_client) {
+               num_retransmits = iph2->ph1->rmconf->retry_counter - iph2->retry_counter;
+               if (num_retransmits == 3) {
+                       /*
+                        * phase2 negotiation is stalling on retransmits, inspite of a valid ph1.
+                        * one of the following is possible:
+                        * - (0) severe packet loss.
+                        * - (1) the peer is dead.
+                        * - (2) the peer is out of sync hence dropping this phase2 rekey (and perhaps responding with insecure 
+                        *       invalid-cookie notifications... but those are untrusted and so we can't rekey phase1 off that)
+                        *              (2.1) the peer rebooted (or process restarted) and is now alive.
+                        *     (2.2) the peer has deleted phase1 without notifying us (or the notification got dropped somehow).
+                        *     (2.3) the peer has a policy/bug stopping this phase2 rekey
+                        *
+                        * in all these cases, one sure way to know is to trigger a phase1 rekey early.
+                        */
+                       plog(LLV_DEBUG2, LOCATION, NULL, "many phase2 retransmits: try phase1 rekey and this phase2 to quit earlier.\n");
+                       isakmp_ph1rekeyexpire(iph2->ph1, TRUE);
+                       iph2->retry_counter = 0;
+               }
+       }
+}
index e840c37106a8ccf409843df959e35199a4aab7c5..4d4854c7d6ae335e1958ed74d64ea92e94212e8a 100644 (file)
@@ -96,6 +96,7 @@ struct ike_session {
     int                                  i_sent_data_sc_dpd:1;
     int                                  i_sent_data_sc_idle:1;
     int                                         is_client:1;
+    time_t                               last_time_data_sc_detected;
     u_int32_t                            natt_flags;
        char                                *term_reason;
 
@@ -152,5 +153,7 @@ extern int                ike_session_is_client_ph1_rekey __P((struct ph1handle
 extern void               ike_session_start_xauth_timer __P((struct ph1handle *));
 extern void               ike_session_stop_xauth_timer __P((struct ph1handle *));
 extern int                ike_session_get_sainfo_r __P((struct ph2handle *));
+extern int                ike_session_drop_rekey __P((ike_session_t *));
+extern void               ike_session_ph2_retransmits __P((struct ph2handle *));
 
 #endif /* _IKE_SESSION_H */
index 7bcf121a70a9b28fb5559e25b27aba34ad5a2c03..f499850197acc2aa69f4335d20b2a0d9de6182ce 100644 (file)
@@ -2317,6 +2317,8 @@ isakmp_ph2resend(iph2)
                                isakmp_pindex(&iph2->ph1->index, iph2->msgid));
                EVT_PUSH(iph2->src, iph2->dst, EVTT_PEER_NO_RESPONSE, NULL);
                return -1;
+       } else {
+               ike_session_ph2_retransmits(iph2);
        }
 
        if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0){
@@ -2412,12 +2414,13 @@ isakmp_ph1rekeyexpire_stub(p)
 void *p;
 {
        
-       isakmp_ph1rekeyexpire((struct ph1handle *)p);
+       isakmp_ph1rekeyexpire((struct ph1handle *)p, FALSE);
 }
 
 void
-isakmp_ph1rekeyexpire(iph1)
+isakmp_ph1rekeyexpire(iph1, ignore_sess_drop_policy)
 struct ph1handle *iph1;
+int               ignore_sess_drop_policy;
 {
        char              *src, *dst;
        struct remoteconf *rmconf;
@@ -2443,6 +2446,10 @@ struct ph1handle *iph1;
        racoon_free(src);
        racoon_free(dst);
 
+       if (!ignore_sess_drop_policy && ike_session_drop_rekey(iph1->parent_session)) {
+               return;
+       }
+
        // exit if there is another ph1 that is established (with a pending rekey timer)
        if (ike_session_has_other_established_ph1(iph1->parent_session, iph1)) {
                plog(LLV_INFO, LOCATION, iph1->remote,
index 9ed13efc24f716e2d43a736dca1de11b10b9ea92..44fa30f951ae04f2222fb2d64c9c9aeb29a40cbc 100644 (file)
@@ -635,7 +635,7 @@ isakmp_info_recv_d(iph1, delete, msgid, encrypted)
                 del_ph1->parent_session &&
                 del_ph1->parent_session->is_client &&
                 del_ph1->parent_session->established) {
-                isakmp_ph1rekeyexpire(del_ph1);
+                isakmp_ph1rekeyexpire(del_ph1, FALSE);
             }
             
                        EVT_PUSH(del_ph1->local, del_ph1->remote,
@@ -658,7 +658,11 @@ isakmp_info_recv_d(iph1, delete, msgid, encrypted)
                                                address = ((struct sockaddr_in *)(iph1->remote))->sin_addr.s_addr;
                                        else
                                                address = 0;
-                                       vpncontrol_notify_ike_failed(VPNCTL_NTYPE_PH1_DELETE, FROM_REMOTE, address, 0, NULL);
+                                       if (iph1->cert && IS_CERT_STATUS_ERROR(iph1->cert->status)) {
+                                               vpncontrol_notify_ike_failed(VPNCTL_NTYPE_PH1_DELETE_CERT_ERROR + iph1->cert->status, FROM_REMOTE, address, 0, NULL);
+                                       } else {
+                                               vpncontrol_notify_ike_failed(VPNCTL_NTYPE_PH1_DELETE, FROM_REMOTE, address, 0, NULL);
+                                       }
                                }
 #endif
                        isakmp_ph1expire(del_ph1);
index d6dc017f5deaf3ba078790569a9628160d17787b..a3edc8bd9f585568c3226d78a0ef45917db24462 100644 (file)
@@ -89,7 +89,7 @@ extern int isakmp_ph2resend __P((struct ph2handle *));
 extern void isakmp_ph1expire_stub __P((void *));
 extern void isakmp_ph1expire __P((struct ph1handle *));
 extern void isakmp_ph1rekeyexpire_stub __P((void *));
-extern void isakmp_ph1rekeyexpire __P((struct ph1handle *));
+extern void isakmp_ph1rekeyexpire __P((struct ph1handle *, int));
 extern int  isakmp_ph1rekeyretry __P((struct ph1handle *));
 extern void isakmp_ph1delete_stub __P((void *));
 extern void isakmp_ph1delete __P((struct ph1handle *));
index 139c3db032d0d6d7e01bba474e29666bdb9e5ae9..0fad2e6e4c78b5a13f94dc18f6a6c86da483351d 100644 (file)
 #include <CoreFoundation/CoreFoundation.h>
 #endif
 #include "remoteconf.h"
+#include "vpn_control.h"
 
 #ifdef HAVE_GSSAPI
 #include "gssapi.h"
@@ -1520,7 +1521,7 @@ oakley_validate_auth(iph1)
                                        } else
                                                hostname = CFStringCreateWithBytes(NULL, (u_int8_t *)id_spec->id->v, id_spec->id->l, kCFStringEncodingUTF8, FALSE);
                                }
-                               error = crypto_cssm_check_x509cert(&iph1->cert_p->cert, hostname);
+                               error = crypto_cssm_check_x509cert(&iph1->cert_p->cert, hostname, iph1->cert_p->status);
                                if (hostname)
                                        CFRelease(hostname);
                        }
@@ -1528,7 +1529,7 @@ oakley_validate_auth(iph1)
 #else /* TARGET_OS_EMBEDDED */
 #ifdef __APPLE__
                                if (iph1->rmconf->cert_verification == VERIFICATION_MODULE_SEC_FRAMEWORK)
-                                       error = crypto_cssm_check_x509cert(&iph1->cert_p->cert, NULL);
+                                       error = crypto_cssm_check_x509cert(&iph1->cert_p->cert, NULL, iph1->cert_p->status);
                                else 
 #endif /* __APPLE__ */
                                {
@@ -1728,11 +1729,27 @@ int
 oakley_getmycert(iph1)
        struct ph1handle *iph1;
 {
+       int     err;
+       u_int32_t address;
+       
        switch (iph1->rmconf->certtype) {
                case ISAKMP_CERT_X509SIGN:
                        if (iph1->cert)
                                return 0;
-                       return get_cert_fromlocal(iph1, 1);
+/* only do the local cert test on the phone */
+               {
+                       if ( !(err = get_cert_fromlocal(iph1, 1))){
+                               if ( iph1->cert->status == CERT_STATUS_EXPIRED || iph1->cert->status == CERT_STATUS_PREMATURE){
+                                       if (iph1->remote->sa_family == AF_INET)
+                                               address = ((struct sockaddr_in *)(iph1->remote))->sin_addr.s_addr;
+                                       else
+                                               address = 0;
+                                       vpncontrol_notify_ike_failed(VPNCTL_NTYPE_PH1_DELETE_CERT_ERROR + iph1->cert->status, FROM_LOCAL, address, 0, NULL);
+                                       return -1;
+                               }
+                       }
+               }
+                       return err;
 
                case ISAKMP_CERT_PLAINRSA:
                        if (iph1->rsa)
@@ -1764,6 +1781,7 @@ get_cert_fromlocal(iph1, my)
        cert_t **certpl;
        char *certfile;
        int error = -1;
+       cert_status_t status = CERT_STATUS_OK;
 
        if (my) {
                certfile = iph1->rmconf->mycertfile;
@@ -1790,7 +1808,8 @@ get_cert_fromlocal(iph1, my)
                        
                        if (iph1->rmconf->keychainCertRef == NULL || base64toCFData(iph1->rmconf->keychainCertRef, &dataRef))
                                goto end;
-                       cert = crypto_cssm_get_x509cert(dataRef);
+                       cert = crypto_cssm_get_x509cert(dataRef, &status);
+                       plog(LLV_DEBUG, LOCATION, NULL, "done with chking cert status %d\n",status);
                        CFRelease(dataRef);
                        break;
                } // else fall thru
@@ -1838,6 +1857,7 @@ get_cert_fromlocal(iph1, my)
        memcpy((*certpl)->pl->v + 1, cert->v, cert->l);
        (*certpl)->pl->v[0] = iph1->rmconf->certtype;
        (*certpl)->type = iph1->rmconf->certtype;
+       (*certpl)->status = status;    
        (*certpl)->cert.v = (*certpl)->pl->v + 1;
        (*certpl)->cert.l = (*certpl)->pl->l - 1;
 
index 5916b16fc711455739215f9ccd0063c2f91d0a35..7b0a60115a34620b76f245bff9dad3fc4e8e5a80 100644 (file)
@@ -162,11 +162,21 @@ struct dhgroup {
        vchar_t *order;
 };
 
+typedef enum cert_status {
+       CERT_STATUS_OK = 0,
+       CERT_STATUS_PREMATURE,
+       CERT_STATUS_EXPIRED,
+       CERT_STATUS_INVALID,
+} cert_status_t;
+
+#define IS_CERT_STATUS_ERROR(status) (status > CERT_STATUS_OK && status < CERT_STATUS_INVALID)
+
 /* certificate holder */
 typedef struct cert_t_tag {
        u_int8_t type;          /* type of CERT, must be same to pl->v[0]*/
        vchar_t cert;           /* pointer to the CERT */
        vchar_t *pl;            /* CERT payload minus isakmp general header */
+       cert_status_t status;
 } cert_t;
 
 struct ph1handle;
index 390cb197a25bcaa3dd7eb8e8839a48ee1cca1a62..4ff5db301eb76796a336843028cbc0f32d502fb6 100644 (file)
@@ -1413,7 +1413,8 @@ pk_recvupdate(mhp)
 #endif
 
        /* count up */
-       iph2->ph1->ph2cnt++;
+       if (iph2->ph1)
+               iph2->ph1->ph2cnt++;
 
        /* turn off schedule */
        if (iph2->scr)
@@ -1831,7 +1832,8 @@ pk_recvexpire(mhp)
        /* INITIATOR, begin phase 2 exchange only if there's no other established ph2. */
        /* allocate buffer for status management of pfkey message */
        if (iph2->side == INITIATOR &&
-               !ike_session_has_other_established_ph2(iph2->parent_session, iph2)) {
+               !ike_session_has_other_established_ph2(iph2->parent_session, iph2) &&
+               !ike_session_drop_rekey(iph2->parent_session)) {
 
                initph2(iph2);
 
index fd545d8b4abd916e04feb5f04cb24c296232fe3d..7f52515fa636d972237d0462634febfe6aab7354 100644 (file)
@@ -290,6 +290,9 @@ struct vpnctl_cmd_start_dpd {
 #define VPNCTL_NTYPE_PEER_DEAD                                 50001   /* detected by DPD */
 #define VPNCTL_NTYPE_PH1_DELETE                                        50002   /* received a delete payload leaving no PH1 SA for the remote address */
 #define VPNCTL_NTYPE_IDLE_TIMEOUT                              50003
+#define VPNCTL_NTYPE_PH1_DELETE_CERT_ERROR                      VPNCTL_NTYPE_IDLE_TIMEOUT /* used for offsetting cert errors */
+#define VPNCTL_NTYPE_PH1_DELETE_CERT_PREMATURE                  50004   /* received a delete payload & there was a cert verification error leaving no PH1 SA for the remote address */
+#define VPNCTL_NTYPE_PH1_DELETE_CERT_EXPIRED                    50005   /* received a delete payload & there was a cert verification error leaving no PH1 SA for the remote address */
 #define VPNCTL_NTYPE_INTERNAL_ERROR                            -1