How to Use Alamofires Servertrustpolicy.Disableevaluation in Swift 3

How to use Alamofires ServerTrustPolicy.disableEvaluation in swift 3

Try this which seems to be working for me -

extension SessionManager {
static func getManager() -> SessionManager{

let serverTrustPolicies: [String: ServerTrustPolicy] = [
"192.168.1.28:8443": .disableEvaluation
]

let configuration = Reqres.defaultSessionConfiguration()
configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders

return Alamofire.SessionManager(
configuration: configuration,
serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
)
}

}

And to use this SessionManager do the following -

var manager: SessionManager?
manager = SessionManager.getManager()
manager?.request// Here is your request call.

How to use Alamofires ServerTrustPolicy.disableEvaluation in swift 5 alamofire 5.0.3

ServerTrustPolicy has been replaced with the protocol ServerTrustEvaluating in Alamofire 5, and DisabledEvaluator has replaced the .disabled enum case. To replicate the custom setup you had before:

private let session: Session = {
let manager = ServerTrustManager(evaluators: ["serverurl.com": DisabledEvaluator()])
let configuration = URLSessionConfiguration.af.default

return Session(configuration: configuration, serverTrustManager: manager)
}()

Alamofire - Use of undeclared type 'ServerTrustPolicy'?

Yes, it appears that Alamofire has changed this, so the documentation seems to be out of date:

The previous ServerTrustPolicy enum has be refactored into classes which implement ServerTrustEvaluating

Reference: https://github.com/Alamofire/Alamofire/pull/2344

Your solution will be dependent on which version of Alamofire you are using. Certainly this would not impact you in versions 4.6.0 or below, so it seems you are using a newer version.

In the latest master branch (representing 5.0.0-beta7 release), it seems the equivalent code you are looking for is the evaluators property on ServerTrustManager, and you can use the provided DefaultTrustEvaluator class for the ServerTrustEvaluating objects. There are several other evaluators in the same file if you require advanced usage.

Related source files: https://github.com/Alamofire/Alamofire/blob/master/Source/ServerTrustEvaluation.swift

How to connect to self signed servers using Alamofire 1.3

There is a way to change the Server Trust Policy of the Alamofire manager shared instance, but it's not recommended. Instead you should create your own customised instance of the manager. Here is the recommended solution, code is Swift 2.0 with Alamofire from swift-2.0 branch, compiled in Xcode7 beta 5.

Creating customised instance of the manager

Because you will not use the request method on the Alamofire, but use the one on your custom manager instead, you need to think of where to store the manager. What I do is to store it as static in my networking wrapper (the class that utilizes Alamofire and deals with my application networking needs). I set it up like this:

private static var Manager : Alamofire.Manager = {
// Create the server trust policies
let serverTrustPolicies: [String: ServerTrustPolicy] = [
"maskeddomain.com": .DisableEvaluation
]
// Create custom manager
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
configuration.HTTPAdditionalHeaders = Alamofire.Manager.defaultHTTPHeaders
let man = Alamofire.Manager(
configuration: NSURLSessionConfiguration.defaultSessionConfiguration(),
serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
)
return man
}()

Next step is to switch all your calls that use Alamofire.request() with Manager.request(), so you should have something like this:

Manager.request(.GET, "http://stackoverflow.com").responseJSON(
completionHandler: { (_, respose, result) -> Void in
if result.isSuccess {
// enjoy your success
} else if result.isFailure {
// deal with your failure
}
})

If you want to change the shared instance of the manager anyway, go here for more info.

Change serverTrustPolicy of Alamofire.SessionManager to still use top-level convenience methods like Alamofire.request

Just create class and call it "NetManager" with static var of type SessionManager in it.

class NetManager {

static var manager : SessionManager = {

// Create the server trust policies
let serverTrustPolicies: [String: ServerTrustPolicy] = [
"my server url": .disableEvaluation
]

// Create custom manager
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders

let manager = Alamofire.SessionManager(
configuration: URLSessionConfiguration.default,
serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
)

return manager
}()

}

Then use it like this:

NetManager.manager
.request(MyRouter.login())
.responseJSON { response in
//
}

Alamofire without evaluation and with sending client certificate

Problem self solved.

now the answer for SENDING CLIENT SIDE CERTIFICATE maybe someone will need it :)

We need PKCS12 to send certificate so

import Foundation

public class PKCS12 {
let label:String?
let keyID:NSData?
let trust:SecTrust?
let certChain:[SecTrust]?
let identity:SecIdentity?

public init(PKCS12Data:NSData,password:String)
{
let importPasswordOption:NSDictionary = [kSecImportExportPassphrase as NSString:password]
var items : CFArray?
let secError:OSStatus = SecPKCS12Import(PKCS12Data, importPasswordOption, &items)

guard secError == errSecSuccess else {
if secError == errSecAuthFailed {
NSLog("ERROR: SecPKCS12Import returned errSecAuthFailed. Incorrect password?")
}
fatalError("SecPKCS12Import returned an error trying to import PKCS12 data")
}

guard let theItemsCFArray = items else { fatalError() }
let theItemsNSArray:NSArray = theItemsCFArray as NSArray
guard let dictArray = theItemsNSArray as? [[String:AnyObject]] else { fatalError() }

func f<T>(key:CFString) -> T? {
for d in dictArray {
if let v = d[key as String] as? T {
return v
}
}
return nil
}

self.label = f(key: kSecImportItemLabel)
self.keyID = f(key: kSecImportItemKeyID)
self.trust = f(key: kSecImportItemTrust)
self.certChain = f(key: kSecImportItemCertChain)
self.identity = f(key: kSecImportItemIdentity)
}
}

extension URLCredential {
public convenience init?(PKCS12 thePKCS12:PKCS12) {
if let identity = thePKCS12.identity {
self.init(
identity: identity,
certificates: thePKCS12.certChain,
persistence: URLCredential.Persistence.forSession)
}
else { return nil }
}
}

we need x509 also to do PKCS12 I was in need of generating certificates dynamically so theres the code bridged from C

-(void) createX509{
OPENSSL_init();

NSString *docPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/cert"];
NSString *docPathKey = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/key"];
NSString *docPathp12 = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/p12"];

NSString *dataFile = [NSString stringWithContentsOfFile:docPath
encoding:NSUTF8StringEncoding
error:NULL];

FILE *fp = fopen(docPath.UTF8String, "r");

if(fp == NULL){
fp = fopen(docPath.UTF8String, "w+");
FILE *fpKey = fopen(docPathKey.UTF8String, "w+");

EVP_PKEY * pkey;
pkey = EVP_PKEY_new();

RSA * rsa;
rsa = RSA_generate_key(
2048, /* number of bits for the key - 2048 is a sensible value */
RSA_F4, /* exponent - RSA_F4 is defined as 0x10001L */
NULL, /* callback - can be NULL if we aren't displaying progress */
NULL /* callback argument - not needed in this case */
);

EVP_PKEY_assign_RSA(pkey, rsa);

X509 * x509;
x509 = X509_new();

ASN1_INTEGER_set(X509_get_serialNumber(x509), 1);

X509_gmtime_adj(X509_get_notBefore(x509), 0);
X509_gmtime_adj(X509_get_notAfter(x509), 31536000000L);

X509_set_pubkey(x509, pkey);

X509_NAME * name;
name = X509_get_subject_name(x509);

X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC,
(unsigned char *)"CA", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC,
(unsigned char *)"company", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
(unsigned char *)"localhost", -1, -1, 0);

X509_set_issuer_name(x509, name);

X509_sign(x509, pkey, EVP_sha1());

[@"" writeToFile:docPath
atomically:YES
encoding:NSUTF8StringEncoding
error:NULL];
fp = fopen(docPath.UTF8String, "a+");
PEM_write_X509(
fp, /* write the certificate to the file we've opened */
x509 /* our certificate */);
PEM_write_PrivateKey(fpKey, pkey, NULL, NULL, 0, NULL, NULL);
fflush(fpKey);
fclose(fpKey);
fflush(fp);
fclose(fp);
dataFile = [NSString stringWithContentsOfFile:docPath
encoding:NSUTF8StringEncoding
error:NULL];

OpenSSL_add_all_algorithms();
OpenSSL_add_all_ciphers();
OpenSSL_add_all_digests();

PKCS12* p12;
p12 = PKCS12_create("password", "login", pkey, x509, NULL, 0,0,0,0,0);

if(!p12) {
fprintf(stderr, "Error creating PKCS#12 structure\n");
ERR_print_errors_fp(stderr);
exit(1);
}
fp = fopen(docPathp12.UTF8String, "w+");

if (!(fp = fopen(docPathp12.UTF8String, "wb"))) {
ERR_print_errors_fp(stderr);
exit(1);
}
i2d_PKCS12_fp(fp, p12);
PKCS12_free(p12);
fflush(fp);
fclose(fp);

}

The pkcs12 and x05 is now made so we continue in swift

 public let alamofireManager: SessionManager = {
let obj = OpenSSL();
obj.createX509()

var path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first;
var certPEM:String!;
var keyPEM:String!;
var certificateToPin:SecCertificate!;
var pkcs12:PKCS12?;
do{
try certPEM = String(contentsOfFile: path! + "/cert").replacingOccurrences(of: "\n", with: "")
try keyPEM = String(contentsOfFile: path! + "/key").replacingOccurrences(of: "\n", with: "")
let p12 = NSData(contentsOfFile: path! + "/p12");
pkcs12 = PKCS12.init(PKCS12Data: p12!, password: "password")

let docsurl = try! FileManager.default.url(for:.documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)

let urlAp = docsurl.appendingPathComponent("cert");
var cert64 = certPEM.replacingOccurrences(of: "-----BEGIN CERTIFICATE-----", with: "")
cert64 = cert64.replacingOccurrences(of: "-----END CERTIFICATE-----", with: "")
let certificateData = NSData(base64Encoded: cert64, options: .ignoreUnknownCharacters)
certificateToPin = SecCertificateCreateWithData(kCFAllocatorMalloc, certificateData!)

var trust: SecTrust?

let policy = SecPolicyCreateBasicX509()
let status = SecTrustCreateWithCertificates(certificateToPin!, policy, &trust)
let publicKey:SecKey?;
if status == errSecSuccess {
publicKey = SecTrustCopyPublicKey(trust!)!;
}

let dictionary = SecPolicyCopyProperties(policy)

}catch{
print("err")
}

let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForResource = Request.settings.timeout

let trustPolicies = CertTrustPolicyManager(policies: [:])

var serverTrustPolicy:[String: ServerTrustPolicy] = [
Router.baseURLString : .pinCertificates(
certificates: [certificateToPin],
validateCertificateChain: false,
validateHost: false)
]

var alamofireManager:SessionManager = Alamofire.SessionManager(configuration: configuration, delegate: SessionDelegate(), serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicy))

alamofireManager.delegate.sessionDidReceiveChallenge = { session, challenge in
var disposition: URLSession.AuthChallengeDisposition = .useCredential
var credential: URLCredential?

if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
disposition = URLSession.AuthChallengeDisposition.useCredential
credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)

} else {
if challenge.previousFailureCount > 0 {
disposition = .cancelAuthenticationChallenge
} else {
credential = alamofireManager.session.configuration.urlCredentialStorage?.defaultCredential(for: challenge.protectionSpace)

if credential != nil {
disposition = .useCredential
}
}
}

let certs = [certificateToPin]
let persist = URLCredential.Persistence.forSession;

return (disposition, URLCredential.init(PKCS12: pkcs12!))
}

return alamofireManager
}()

There I was in need to get certificates, probably some of code is useless or badly wrote but its working ( I'm new to IOS :) ), I was also converting PEM certificates to DER there but after these operations I was finally able to do insecure connection with sending client side and created certificate with Alamofire.

The code above is gathered from everywhere!

Cheers



Related Topics



Leave a reply



Submit