Send CSR's and retreive certificates to/from ca-server
's from your own Swift based client and server apps. Certificatable
allows any object to support certificates while ParseCertificatable
allows any ParseObject from Parse-Swift. ParseCertificateAuthority
helps developers add an extra layer of security to their apps by making it easy to enable certificate pinning, authentication/verification, encrypting/decrypting, and secure device-to-device offline communication with key/certificate exchange.
- ca-server - A certificate authority(CA) that can turn CSR's into certificates
- CertificateSigningRequest - Generate CSR's on Swift clients and servers that can later be signed by
ca-server
- Parse-Swift - Write Parse client apps in Swift. When coupled with ParseCertificateAuthority and CertificateSigningRequest, provides the complete client-side stack for generating CSR's, sending/receiving certificates to/from
ca-server
- ParseServerSwift - Write Parse Server Cloud Code apps in Swift. When coupled with ParseCertificateAuthority, CertificateSigningRequest, and Parse-Swift provides the complete server-side stack for generating CSR's, sending/receiving certificates to/from
ca-server
Setup a Vapor project by following the directions for installing and setting up your project on macOS or linux.
In your Package.swift
file add ParseCertificateAuthority
to dependencies
:
// swift-tools-version:5.5.2
import PackageDescription
let package = Package(
name: "YOUR_PROJECT_NAME",
dependencies: [
.package(url: "https://github.com/netreconlab/ParseCertificateAuthority", .upToNextMajor(from: "0.1.0")),
]
)
import ParseCertificateAuthority
// Innitialize ParseCertificateAuthority
let caConfiguration = try ParseCertificateAuthorityConfiguration(caURLString: "http://certificate-authority:3000", // The url for `ca-server`.
caRootCertificatePath: "/ca_certificate", // The root certificate path on `ca-server`.
caCertificatesPath: "/certificates/", // The certificates path on `ca-server`.
caUsersPath: "/appusers/") // The user path on `ca-server`.
initialize(configuration: caConfiguration)
Below is an example of conforming to ParseCertificatable
if you are using Parse-Swift
. If you are not using Parse-Swift
, the process is similar except you conform to Certificatable
and use the relevant methods. At least one of your ParseObject
models need to conform to ParseCertificatable
. A good candidate is a model that already conforms to ParseInstallatiion
as this is unique per installation on each device.
// Conform to `ParseCertificatable`. If not using Parse-Swift, conform to `Certificatable` instead.
struct Installation: ParseInstallation, ParseCertificatable {
var rootCertificate: String?
var certificate: String?
var csr: String?
var certificateId: String? {
installationId
}
...
}
Once you have a CSR from a package like CertificateSigningRequest, you can create an account for the current ParseUser
automatically and send the CSR to a ca-server by doing the following:
do {
let user = User.current // Some user type that conforms to `ParseUser`.
var installation = Installation.current
let (certificate, rootCertificate) = try await installation.getCertificates(user)
if installation.certificate != certificate || installation.rootCertificate != rootCertificate {
installation.certificate = certificate
installation.rootCertificate = rootCertificate
try await installation.save()
// Notify the user their object has been updated with the certificates
}
} catch {
// Handle error
}
Creating a new certificate for a CSR can be useful when a certificate has expired. To generage a new certificate, do the following:
do {
let user = User.current // Some user type that conforms to `ParseUser`.
var installation = Installation.current
let (certificate, rootCertificate) = try await installation.requestNewCertificates(user)
guard let certificate = certificate,
let rootCertificate = rootCertificate else {
let error = ParseError(code: .otherCause,
message: "Could not get new certificates")
return
}
installation.certificate = certificate
installation.rootCertificate = rootCertificate
try await installation.save()
// Notify the user their object has been updated with the certificates
} catch {
// Handle error
}