title: How to securely upload files with Alamofire in a local server using TLS and self-signed certificates?
body: <p>I am able to successfuly upload files on a local server (implemented in node.js) using Alamofire 5 with ATS <code>Allow Arbitrary Loads</code> and the following snippet:</p>
  
  <pre><code>struct httpBinResponse: Decodable { let url: String }
  let url = "http://10.0.0.2:443/upload"
  let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
  guard let fileURL : URL = path.appendingPathComponent("F06F34EC-0BFD-4201-8405-7CED956CA299.zip") else {return}
  AF.upload(multipartFormData:
      {(multipart) in multipart.append(fileURL, withName: "file", fileName: fileURL.lastPathComponent, mimeType: "application/octet-stream" )},
      to: url)
      .responseDecodable(of: httpBinResponse.self) { response in
          debugPrint(response)
  }
  </code></pre>
  
  <p>I was able to switch to HTTPS in the local server and I can upload files with Postman using self-signed ca/client and server certificates. 
  I have read posts for self-signed certificate pinning but I am not sure if I need to pin or authenticate. </p>
  
  <p>What is the best practice that involves TLS in a local server with self-signed certificates and Alamofire?</p>
  
  <p><strong>EDIT 5/4/20:</strong>
  Following suggestions from different sources, I made progress by adding the following: </p>
  
  <pre><code>struct Certificates {
      static let ca: SecCertificate = Certificates.certificate(filename: "ca")
  
      private static func certificate(filename: String) -&gt; SecCertificate {
          let filePath = Bundle.main.path(forResource: filename, ofType: "der")!
          let data = try! Data(contentsOf: URL(fileURLWithPath: filePath))
          let certificate = SecCertificateCreateWithData(nil, data as CFData)!
          return certificate
      }
  }
  </code></pre>
  
  <p>And in inside my class I have added:</p>
  
  <pre><code>private let secureSession: Session = {
      let certificates : [SecCertificate] = [Certificates.ca]
  
      let pinnedCertEvaluator = PinnedCertificatesTrustEvaluator(certificates: certificates,
                                                                 acceptSelfSignedCertificates: true,
                                                                 performDefaultValidation: false,
                                                                 validateHost: false)
      let manager = ServerTrustManager(evaluators: ["10.0.0.2": pinnedCertEvaluator])
      let configuration = URLSessionConfiguration.af.default
  
      return Session(configuration: configuration, serverTrustManager: manager)
  }()
  </code></pre>
  
  <p>After adding the above I was able to use https to upload the files. I am not sure why I have to set <code>performDefaultValidation</code> and <code>validateHost</code> to <code>false</code> to avoid getting <code>Alamofire.AFError.serverTrustEvaluationFailed</code>. Is this the right way to go? Another point I am trying to figure out is why do I only need the ca root certificate for pinning? </p>