@@ -330,7 +330,7 @@ import CZitiPrivate
330330 }
331331
332332 // Store certificates
333- let certs = dropFirst ( " pem: " , resp. id. cert)
333+ let certs = dropFirst ( " pem: " , resp. id. cert! )
334334 _ = zkc. deleteCertificate ( silent: true )
335335 // storeCertificate only stores the first (leaf) certificate in the pem. that's ok - the full chain of certs is stored in the .zid
336336 // file. only the leaf/pubkey needs to be in the keychain.
@@ -348,7 +348,28 @@ import CZitiPrivate
348348 }
349349
350350 let zid = ZitiIdentity ( id: subj, ztAPIs: resp. ztAPIs, certs: certs, ca: ca)
351- log. info ( " Enrolled id: \( subj) with controller: \( zid. ztAPI) , cert: \( resp. id. cert) " , function: " enroll() " )
351+ log. info ( " Enrolled id: \( subj) with controller: \( zid. ztAPI) , cert: \( resp. id. cert!) " , function: " enroll() " )
352+
353+ enrollCallback ( zid, nil )
354+ }
355+ }
356+
357+ @objc public static func enroll( controllerURL: String , _ enrollCallback: @escaping EnrollmentCallback ) {
358+ ZitiEnroller . enroll ( url: controllerURL) { resp, _, zErr in
359+ guard let resp = resp, zErr == nil else {
360+ log. error ( String ( describing: zErr) , function: " enroll() " )
361+ enrollCallback ( nil , zErr)
362+ return
363+ }
364+
365+ // Grab CA if specified
366+ var ca = resp. id. ca
367+ if let idCa = resp. id. ca {
368+ ca = dropFirst ( " pem: " , idCa)
369+ }
370+
371+ let zid = ZitiIdentity ( id: controllerURL, ztAPIs: resp. ztAPIs, ca: ca)
372+ log. info ( " Enrolled id: \( zid. id) with controller: \( zid. ztAPI) " , function: " enroll() " )
352373
353374 enrollCallback ( zid, nil )
354375 }
@@ -383,24 +404,35 @@ import CZitiPrivate
383404 /// - See also:
384405 /// - `runAsync(_:)`
385406 @objc public func run( _ postureChecks: ZitiPostureChecks ? , _ initCallback: @escaping InitCallback ) {
386- // Get certificate
407+ // Get certificates. There won't be any if this identity uses external authentication.
387408 let zkc = ZitiKeychain ( tag: id. id)
388- guard let certPEM = id. getCertificates ( zkc) else {
389- let errStr = " unable to retrieve certificates "
390- log. error ( errStr)
391- initCallback ( ZitiError ( errStr) )
392- return
409+ var certPEMPtr : UnsafeMutablePointer < Int8 > ? = nil
410+ let certPEM = id. getCertificates ( zkc)
411+ if ( certPEM != nil ) {
412+ certPEMPtr = UnsafeMutablePointer< Int8> . allocate( capacity: certPEM!. count + 1 )
413+ certPEMPtr!. initialize ( from: certPEM!, count: certPEM!. count + 1 )
414+ } else {
415+ // is there any way to know at this point that ext auth is needed? maybe check ext auth signers? add "extAuthEnabled" field?
416+ //let errStr = "unable to retrieve certificates"
417+ //log.error(errStr)
418+ //initCallback(ZitiError(errStr))
419+ //return
393420 }
394421
395422 // Get private key
396- guard let privKey = zkc. getPrivateKey ( ) else {
397- let errStr = " unable to retrieve private key from keychain "
398- log. error ( errStr)
399- initCallback ( ZitiError ( errStr) )
400- return
423+ var privKeyPEMPtr : UnsafeMutablePointer < Int8 > ? = nil
424+ if let privKey = zkc. getPrivateKey ( ) {
425+ let privKeyPEM = zkc. getKeyPEM ( privKey)
426+ privKeyPEMPtr = UnsafeMutablePointer< Int8> . allocate( capacity: privKeyPEM. count + 1 )
427+ privKeyPEMPtr!. initialize ( from: privKeyPEM, count: privKeyPEM. count + 1 )
428+ } else {
429+ // check if we should have a key (same deal as with cert above)
430+ //let errStr = "unable to retrieve private key from keychain"
431+ //log.error(errStr)
432+ //initCallback(ZitiError(errStr))
433+ //return
401434 }
402- let privKeyPEM = zkc. getKeyPEM ( privKey)
403-
435+
404436 // init ziti
405437 self . initCallback = initCallback
406438 self . postureChecks = postureChecks
@@ -416,12 +448,6 @@ import CZitiPrivate
416448 let ctrlPtr = UnsafeMutablePointer< Int8> . allocate( capacity: id. ztAPI. count + 1 )
417449 ctrlPtr. initialize ( from: id. ztAPI, count: id. ztAPI. count + 1 )
418450
419- let certPEMPtr = UnsafeMutablePointer< Int8> . allocate( capacity: certPEM. count + 1 )
420- certPEMPtr. initialize ( from: certPEM, count: certPEM. count + 1 )
421-
422- let privKeyPEMPtr = UnsafeMutablePointer< Int8> . allocate( capacity: privKeyPEM. count + 1 )
423- privKeyPEMPtr. initialize ( from: privKeyPEM, count: privKeyPEM. count + 1 )
424-
425451 var caPEMPtr : UnsafeMutablePointer < Int8 > ? = nil // todo empty string
426452 if ( id. ca != nil ) {
427453 caPEMPtr = UnsafeMutablePointer< Int8> . allocate( capacity: id. ca!. count + 1 )
@@ -451,8 +477,8 @@ import CZitiPrivate
451477 var zitiStatus = ziti_context_init ( & self . ztx, & zitiCfg)
452478
453479 ctrlPtr. deallocate ( )
454- certPEMPtr. deallocate ( )
455- privKeyPEMPtr. deallocate ( )
480+ if let certPEMPtr = certPEMPtr { certPEMPtr . deallocate ( ) }
481+ if let privKeyPEMPtr = privKeyPEMPtr { privKeyPEMPtr . deallocate ( ) }
456482 caPEMPtr? . deallocate ( )
457483
458484 withUnsafeMutablePointer ( to: & ctrls) { ctrlListPtr in
@@ -826,7 +852,18 @@ import CZitiPrivate
826852 mfaAuthResponseStatusCallback = cb
827853 ziti_mfa_auth ( ztx, code. cString ( using: . utf8) , Ziti . onMfaAuthResponseStatus, self . toVoidPtr ( ) )
828854 }
829-
855+
856+ /// Type definition of callback method for external authentication
857+ public typealias ExtAuthCallback = ( _ ziti: Ziti , _ url: String , _ ctx: UnsafeMutableRawPointer ? ) -> Void
858+ private var extAuthStatusCallback : ExtAuthCallback ?
859+ public func extAuth( _ provider: String , _ cb: @escaping ExtAuthCallback ) {
860+ extAuthStatusCallback = cb
861+ let cProvider = provider. cString ( using: . utf8)
862+ let cProviderCpy = copyString ( cProvider) // grr
863+ ziti_use_ext_jwt_signer ( ztx, cProviderCpy)
864+ ziti_ext_auth ( ztx, Ziti . onExtAuthStatus, self . toVoidPtr ( ) )
865+ freeString ( cProviderCpy)
866+ }
830867 // MARK: - Static C Callbacks
831868
832869 static private let onMfaAuthResponseStatus : ziti_mfa_cb = { ztx, status, ctx in
@@ -1126,6 +1163,14 @@ import CZitiPrivate
11261163 }
11271164 }
11281165
1166+ static private let onExtAuthStatus : ziti_ext_auth_launch_cb = { ztx, url, ctx in
1167+ guard let mySelf = zitiUnretained ( Ziti . self, ctx) else {
1168+ log. wtf ( " invalid context " )
1169+ return
1170+ }
1171+ mySelf. extAuthStatusCallback ? ( mySelf, String ( cString: url!) , ctx)
1172+ }
1173+
11291174 // MARK: - Helpers
11301175
11311176 private static func dropFirst( _ drop: String , _ str: String ) -> String {
0 commit comments