3 Replies
      Latest reply: Feb 6, 2017 3:29 PM by eskimo RSS
      mo.o Level 1 Level 1 (0 points)

        First of all, sorry for my english.

        i want iOS mutual authentication with client certificate.

        but when i make NSURLCredential for NSURLAuthenticationMethodClientCertificate,

        i have to need SecIdentityRef. but i cannot obtain identity from anywhere..

         

        1.

        i created keypair with SecKeyGeneratePair (RSA, 2048). and stored into keychain.

         

        2.

        send publickey to server. and get PEM type certificate (base64) from server, correctly.

         

        3.

        i decoded it. and make certificate with SecCertificateCreateWithData,

        store it keychain directly

        NSDictionary* certDic = @{
                                          (__bridge id)kSecClass : (__bridge id)kSecClassCertificate,
                                          (__bridge id)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
                                          (__bridge id)kSecValueRef : (__bridge id)savedCertRef,
                                          (__bridge id)kSecAttrLabel : cert_tag,
                                          };
        
        OSStatus status = SecItemAdd((__bridge CFDictionaryRef)certDic, NULL);
        

        perfectly work until here.

         

        4.

        now my keychain stored "Private Key", "Public Key","Certificate" from server

         

        5.

        when i try to access server, server request client certificate.

        so i have to send client certificate from my keychain

        but i have only SecCertificateRef. at that time. there is no SecIdentityRef


        //in NSURLAuthenticationMethodClientCertificate block...
        
        SecCertificateRef certificate = [DeviceCertificateControl getDeviceCertRef];
        SecIdentityRef identity = ??????????????????;
                   
        NSArray *certArray = [NSArray arrayWithObject:(__bridge id)certificate];
        * credential = [NSURLCredential credentialWithIdentity:identity certificates:certArray persistence:NSURLCredentialPersistencePermanent];
        

         

        :::::::::: question.

        1. how to make SecIdentityRef with SecCertificateRef with private key ref?

        (many other examples, they use P12 file (pkcs#12), but i don't use it)

         

        2. can i make pkcs#12 type data directly in iOS device?


        3. is there way to send certification without identity?


        many thanks.

        • Re: generate SecIdentityRef with SecCertificateRef, private key
          eskimo Apple Staff Apple Staff (6,075 points)

          I’m going to tackle your questions out of order:

          3. is there way to send certification without identity?

          This makes no sense.  My TLS for App Developers post explains why.

          2. can i make pkcs#12 type data directly in iOS device?

          Not via any iOS APIs.  A PKCS#12 is just a bag of bytes, so you could write or acquire code to create one, but it’s not a lot of fun.  It would be easier to fix your identity code.

          1. how to make SecIdentityRef with SecCertificateRef with private key ref?

          You need to do three things:

          • Before adding the certificate to the keychain, delete the public key from the keychain.  There are situations where the presence of the public key confuses the identity matching code (r. 15615260).

          • Identity matching is done via the public key hash, which should be stored in the kSecAttrLabel kSecAttrApplicationLabel attribute of the private key and the kSecAttrPublicKeyHash attribute of the certificate.  After you’ve got both items in the keychain, get these attributes to confirm that they match up.

          • Once the above is sorted out, you can get the identity by calling SecItemCopyMatching looking for items where the kSecClass is kSecClassIdentity.

          Share and Enjoy

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

            • Re: generate SecIdentityRef with SecCertificateRef, private key
              TirantFox Level 1 Level 1 (0 points)

              @eskimo Thank you for your contribution. This information is very difficult to find.

               

              I am in a similar predicament, in which I've created a key pair and CSR on my iOS app, sent the CSR to the server and received a PEM certificate back. So I have now at my disposal the Private Key, Public Key and the CA Signed Certificate.

               

              How do I determine the public key hash to follow your instructions here? How do I determine the ThumbprintAlgorithm used in the certificate without access to SecCertificateCopyValues?

               

              Any thoughts on why these functions are not included in the iOS API

                • Re: generate SecIdentityRef with SecCertificateRef, private key
                  eskimo Apple Staff Apple Staff (6,075 points)

                  How do I determine the public key hash to follow your instructions here?

                  You can actually the public key hash if necessary, but my experience is that it’s not necessary.  If you add the certificate to the keychain as a ref (that is, using kSecValueRef rather than kSecValueData), the system should set that attribute for you, at which point you can call SecItemCopyMatching to get an identity object.

                  Share and Enjoy

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