4 Replies
      Latest reply on Mar 15, 2016 5:42 AM by emcelik
      emcelik Level 1 Level 1 (0 points)

        Hi,

         

        I'am new on objective c programming.

        Depends on the related documents, I've tried to create IPSEC VPN and connect automatically from my application.

        I've used below code to create and connect IPSEC VPN but it is giving "No VPN Shared Secret was provided" error.

        If I try to add vpn configuration from my Iphone with same parameters it's connecting succesfully.

        I spent 3 days to solve this issue but didn't find anything.

         

        [[NEVPNManager sharedManager] setEnabled:YES];

        [[NEVPNManager sharedManager] loadFromPreferencesWithCompletionHandler: ^(NSError *error) {

        NEVPNProtocolIPSec *p = [[NEVPNProtocolIPSec alloc] init];

        p.serverAddress =@"server";

        p.authenticationMethod = NEVPNIKEAuthenticationMethodSharedSecret;

        p.useExtendedAuthentication = YES;

        NSString *secret = @"secretCode";

        NSData *secretData = [secret dataUsingEncoding:NSUTF8StringEncoding];

        p.sharedSecretReference=secretData;

        p.localIdentifier=@"identifier";

        p.username=@"username";

        p.passwordReference=[[SSKeychain passwordForService:@"service" account:@"passwordReference"] dataUsingEncoding:NSUTF8StringEncoding];

        p.disconnectOnSleep = NO;

        [NEVPNManager sharedManager].protocolConfiguration=p;

        NSMutableArray *rules = [[NSMutableArray alloc] init];

        NEOnDemandRuleConnect *connectRule = [NEOnDemandRuleConnect new];

        [rules addObject:connectRule];

        [[NEVPNManager sharedManager] setOnDemandRules:rules];

        [[NEVPNManager sharedManager] setLocalizedDescription:@"vpn"];

        [[NEVPNManager sharedManager] setEnabled:YES];

        [[NEVPNManager sharedManager] saveToPreferencesWithCompletionHandler: ^(NSError *error) {

        NSLog(@"Save VPN to preference complete");

        if (error) {

        NSLog(@"Save error: %@", error);

             }

        }];

        NSError *startError; [[NEVPNManager sharedManager].connection startVPNTunnelAndReturnError:&startError];

        if(startError) { NSLog(@"Start error: %@", startError.localizedDescription); }

        • Re: NeVPNManager No VPN Shared Secret was provided error
          eskimo Apple Staff Apple Staff (11,655 points)

          sharedSecretReference is meant to be a persistent reference to the shared secret in the keychain (like the similarly-named passwordReference), not the shared secret itself.

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"

            • Re: NeVPNManager No VPN Shared Secret was provided error
              emcelik Level 1 Level 1 (0 points)

              Thanks for answer but I've tried with a persistent referance in keychain before but it didn't work.

               

              I'am creating key chain like below and in saveToPreferencesWithCompletionHandler event I'am logging shared secret referance and it's seems ok.

               

               

              NSString* newStr = [[NSString alloc] initWithData:p.sharedSecretReference encoding:NSUTF8StringEncoding];

                          NSLog(@"kod: %@",newStr);

               

               

              NSString *sharedSecret =  @"mysharedsecret";

               

                  NSMutableDictionary *keychainItem = [NSMutableDictionary dictionary];

               

                  keychainItem[(__bridge id)kSecClass] = (__bridge id)kSecClassGenericPassword;

                  keychainItem[(__bridge id)kSecAttrAccessible] = (__bridge id)kSecAttrAccessibleAlways;

                  keychainItem[(__bridge id)kSecValueData] = sharedSecret;

               

              What am i doing wrong ?

                • Re: NeVPNManager No VPN Shared Secret was provided error
                  eskimo Apple Staff Apple Staff (11,655 points)

                  I'am creating key chain like below and in saveToPreferencesWithCompletionHandler event I'am logging shared secret referance and it's seems ok.

                  NSString* newStr = [[NSString alloc] initWithData:p.sharedSecretReference encoding:NSUTF8StringEncoding];
                  NSLog(@"kod: %@",newStr);
                  

                  I’m not sure I fully understand your code but the above snippet makes no sense.  sharedSecretReference is meant to be a keychain persistent reference.  It’s an NSData which, on current systems, contains 12 bytes of binary goo.  For example:

                  (lldb) po p.sharedSecretReference
                  <67_65_6e_70 00_00_00_00 00_00_01_4b>
                  

                  Note I added some underscores to avoid the ire of the DevForums spam checker.

                  There’s no way you can convert that to a string using -initWithData:encoding:.  Which means that if your log statement is showing a string, your shared secret persistent reference is not a persistent reference.

                  Pasted in below is the code that I use to set up my keychain items in my NEVPNManager test app.

                  Share and Enjoy

                  Quinn “The Eskimo!”
                  Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                  let myEmail = "eskimo" + "1" + "@apple.com"

                  - (NSData *)persistentReferenceForSavedPassword:(NSString *)password service:(NSString *)service account:(NSString *)account {
                      NSData *        result;
                      NSData *        passwordData;
                      OSStatus        err;
                      CFTypeRef      secResult;
                  
                      NSParameterAssert(password != nil);
                      NSParameterAssert(service != nil);
                      NSParameterAssert(account != nil);
                  
                      result = nil;
                  
                      passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];
                  
                      err = SecItemCopyMatching( (__bridge CFDictionaryRef) @{
                          (__bridge id) kSecClass:                (__bridge id) kSecClassGenericPassword,
                          (__bridge id) kSecAttrService:          service,
                          (__bridge id) kSecAttrAccount:          account,
                          (__bridge id) kSecReturnPersistentRef:  @YES,
                          (__bridge id) kSecReturnData:          @YES
                      }, &secResult);
                      if (err == errSecSuccess) {
                          NSDictionary *  resultDict;
                          NSData *        currentPasswordData;
                  
                          resultDict = CFBridgingRelease( secResult );
                          assert([resultDict isKindOfClass:[NSDictionary class]]);
                  
                          result = resultDict[ (__bridge NSString *) kSecValuePersistentRef ];
                          assert([result isKindOfClass:[NSData class]]);
                  
                          currentPasswordData = resultDict[ (__bridge NSString *) kSecValueData ];
                          assert([currentPasswordData isKindOfClass:[NSData class]]);
                  
                          if ( ! [passwordData isEqual:currentPasswordData] ) {
                              err = SecItemUpdate( (__bridge CFDictionaryRef) @{
                                  (__bridge id) kSecClass:        (__bridge id) kSecClassGenericPassword,
                                  (__bridge id) kSecAttrService:  service,
                                  (__bridge id) kSecAttrAccount:  account,
                              }, (__bridge CFDictionaryRef) @{
                                  (__bridge id) kSecValueData:    passwordData
                              } );
                              if (err != errSecSuccess) {
                                  NSLog(@"Error %d saving password (SecItemUpdate)", (int) err);
                                  result = nil;
                              }
                          }
                      } else if (err == errSecItemNotFound) {
                          err = SecItemAdd( (__bridge CFDictionaryRef) @{
                              (__bridge id) kSecClass:                (__bridge id) kSecClassGenericPassword,
                              (__bridge id) kSecAttrService:          service,
                              (__bridge id) kSecAttrAccount:          account,
                              (__bridge id) kSecValueData:            passwordData,
                              (__bridge id) kSecReturnPersistentRef:  @YES
                          }, &secResult);
                          if (err == errSecSuccess) {
                              result = CFBridgingRelease( secResult );
                              assert([result isKindOfClass:[NSData class]]);
                          } else {
                              NSLog(@"Error %d saving password (SecItemAdd)", (int) err);
                          }
                      } else {
                          NSLog(@"Error %d saving password (SecItemCopyMatching)", (int) err);
                      }
                      return result;
                  }