Managing TLS Identities

    Description — Couchbase Lite - this content covers how to manage TLS identities using Couchbase Lite
    Related Content — API Reference | Passive Peer | Active Peer

    Description — Couchbase Lite - this content covers how to manage TLS identities using Couchbase Lite
    Related Content — API Reference | Passive Peer | Active Peer

    Overview

    • This describes the configuration and management of TLS identities

    API References

    You can find Objective-C API References here.

    Creating TLS Identity

    There are couple of options by which TLS Identity is created:

    Use Anonymous Cert

    Anonymous certification uses the self signed certificate auto-generated by Couchbase Lite when TLS is enabled, but no TLSIdentity is provided.

    listenerConfig.disableTLS  = false // Use with anonymous self signed cert
    listenerConfig.tlsIdentity = nil

    Import a Cert

    Use the TLSIdentity class’s importIdentity(withData:password:label:error:) method to import a certificate that can be bundled with the app and-or added to the keychain.

    1. First check the keychain to see if the identity already exists

      // Check if Id exists in keychain and if so, use it
      CBLTLSIdentity* identity =
        [CBLTLSIdentity identityWithLabel: @"doco-sync-server" error: &error]; (1)
    2. Check for an existing resource bundle

      // CREATE IDENTITY FROM BUNDLED RESOURCE IF FOUND
      
              // Check for a resource bundle with required label to generate identity from
              // return nil identify if not found
              guard let pathToCert = Bundle.main.path(forResource: "doco-sync-server", ofType: "p12"),
                      let thisData = NSData(contentsOfFile: pathToCert)
                  else
                      {return nil}
    3. Import from an existing resource bundle

      // Use SecPKCS12Import to import the contents (identities and certificates)
      // of the required resource bundle (PKCS #12 formatted blob).
      //
      // Set passphrase using kSecImportExportPassphrase.
      // This passphrase should correspond to what was specified when .p12 file was created
      kcStatus = SecPKCS12Import(thisData as CFData, [String(kSecImportExportPassphrase): "couchbase"] as CFDictionary, &items)
          if kcStatus != errSecSuccess {
           print("failed to import data from provided with error :\(kcStatus) ")
           return nil
          }
      let importedItems = items! as NSArray
      let thisItem = importedItems[0] as! [String: Any]
      
      // Get SecIdentityRef representing the item's id
      let thisSecId = thisItem[String(kSecImportItemIdentity)]  as! SecIdentity
      
      // Get Id's Private Key, return nil id if fails
      var thisPrivateKey : SecKey?
      kcStatus = SecIdentityCopyPrivateKey(thisSecId, &thisPrivateKey)
          if kcStatus != errSecSuccess {
              print("failed to import private key from provided with error :\(kcStatus) ")
              return nil
          }
      
      // Get all relevant certs [SecCertificate] from the ID's cert chain using kSecImportItemCertChain
      let thisCertChain = thisItem[String(kSecImportItemCertChain)] as? [SecCertificate]
      
      // Return nil Id if errors in key or cert chain at this stage
      guard let pKey = thisPrivateKey, let pubCerts = thisCertChain else {
          return nil
      }
    4. Store imported identity in keychain

      // STORE THE IDENTITY AND ITS CERT CHAIN IN THE KEYCHAIN
      
              // Store Private Key in Keychain
              let params: [String : Any] = [
                  String(kSecClass):          kSecClassKey,
                  String(kSecAttrKeyType):    kSecAttrKeyTypeRSA,
                  String(kSecAttrKeyClass):   kSecAttrKeyClassPrivate,
                  String(kSecValueRef):       pKey
              ]
              kcStatus = SecItemAdd(params as CFDictionary, nil)
                  if kcStatus != errSecSuccess {
                      print("Unable to store private key")
                      return nil
                  }
             // Store all Certs for Id in Keychain:
             var i = 0;
             for cert in thisCertChain! {
                  let params: [String : Any] = [
                      String(kSecClass):      kSecClassCertificate,
                      String(kSecValueRef):   cert,
                      String(kSecAttrLabel):  "doco-sync-server"
                      ]
                  kcStatus = SecItemAdd(params as CFDictionary, nil)
                      if kcStatus != errSecSuccess {
                          print("Unable to store certs")
                          return nil
                      }
                  i=i+1
              }
    5. Use keychain identity in config

      // RETURN A TLSIDENTITY FROM THE KEYCHAIN FOR USE IN CONFIGURING TLS COMMUNICATION
      do {
          return try TLSIdentity.identity(withIdentity: thisSecId, certs: [pubCerts[0]])
      } catch {
          print("Error while loading self signed cert : \(error)")
          return nil
      }

    Delete TLS Identity

    [CBLTLSIdentity deleteIdentityWithLabel:thisSecId error: &error];
    Enterprise Edition only
    This an Enterprise Edition feature. Purchase the Enterprise License, which includes official Couchbase Support, to use it in production (see the license and support https://www.couchbase.com/licensing-and-support-faq).