Skip to content

Commit

Permalink
Initial extraction of certificate information
Browse files Browse the repository at this point in the history
Closes #9

Currently only the summary and expiration date are extracted, though the door is open for futher improvements!
  • Loading branch information
James Sherlock committed May 13, 2018
1 parent b294709 commit 3cda1bd
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ import Foundation
public struct DeveloperCertificate: Codable, Equatable {

public let data: Data
public let certificate: SecureCertificate?

// MARK: - Codable

public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
data = try container.decode(Data.self)
certificate = try? SecureCertificate(base64EncodedData: data)
}

public func encode(to encoder: Encoder) throws {
Expand Down
69 changes: 69 additions & 0 deletions Sources/SwiftyProvisioningProfile/Model/SecureCertificate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//
// SecureCertificate.swift
// SwiftyProvisioningProfile
//
// Created by Sherlock, James on 13/05/2018.
//

import Foundation

public struct SecureCertificate: CustomStringConvertible, Equatable {

public enum CertificateError: Error {
case failedToCreate
case failedToObtainSummary
case failedToObtainValues
}

public let summary: String
public let expiryDate: Date?

public init(base64EncodedData: Data) throws {

// Create Certificate

guard let certificate = SecCertificateCreateWithData(nil, base64EncodedData as CFData) else {
throw CertificateError.failedToCreate
}

// Error

var error: Unmanaged<CFError>?

func checkError() throws {
if let error = error {
throw error.takeUnretainedValue()
}
}

// Summary

guard let summary = SecCertificateCopySubjectSummary(certificate) else {
throw CertificateError.failedToObtainSummary
}

self.summary = summary as String

// Values (Expiry)

let valuesKeys = [
kSecOIDInvalidityDate
] as CFArray

let values = SecCertificateCopyValues(certificate, valuesKeys, &error)
try checkError()

guard let dictionary = values as? Dictionary<CFString, Any> else {
throw CertificateError.failedToObtainValues
}

let expiryDateDictionary = dictionary[kSecOIDInvalidityDate] as? [String: Any]
expiryDate = expiryDateDictionary?["value"] as? Date

}

public var description: String {
return "\(summary), Expires: \(expiryDate?.description ?? "No Expiry Date")"
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class SwiftyProvisioningProfileTests: XCTestCase {
let data = try Data(contentsOf: url)
let profile = try ProvisioningProfile.parse(from: data)

print(profile)
print(profile.developerCertificates.flatMap({ $0.certificate?.description }).joined(separator: "\n"))
}

// TODO: Create or find a simple & usable profile and wrtie actual tests for it
Expand Down

0 comments on commit 3cda1bd

Please sign in to comment.