https://github.com/kryptco/swift-pgp
A pure Swift library for parsing and creating PGP RFC 4880 public keys, user ids, and signatures.
https://github.com/kryptco/swift-pgp
Last synced: 11 months ago
JSON representation
A pure Swift library for parsing and creating PGP RFC 4880 public keys, user ids, and signatures.
- Host: GitHub
- URL: https://github.com/kryptco/swift-pgp
- Owner: kryptco
- License: other
- Archived: true
- Created: 2017-05-15T12:32:27.000Z (about 9 years ago)
- Default Branch: master
- Last Pushed: 2019-06-18T18:15:14.000Z (about 7 years ago)
- Last Synced: 2024-11-29T18:40:38.038Z (over 1 year ago)
- Language: Swift
- Homepage: https://krypt.co
- Size: 105 KB
- Stars: 68
- Watchers: 7
- Forks: 17
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# swift-pgp
A pure1 Swift library for parsing and creating PGP [RFC 4880](https://tools.ietf.org/html/rfc4880) public keys, user ids, and signatures. This library is designed to be public-key-cryptography-implementation-agnostic. That is, you can use swift-pgp with any public-key crypto implementation you choose, provided it is either an RSA or Ed25519 cryptosystem.
> **1**. Except for SHA hash functions from CommonCrypto.
This library was created for __Krypton__.
For more information, check out [krypt.co](https://krypt.co).
# Supported Features
Currently, swift-pgp only signatures for certifications and binary documents, but it's abstracted to support the full RFC 4880 spec, see the next section for whats in the pipeline.
- Public Keys: parse and create PGP public keys
- [x] RSA
- [x] Ed25519 (via ext. [eddsa draft](https://tools.ietf.org/html/draft-koch-eddsa-for-openpgp-00))
- Signatures: parse and create PGP Signatures
- [x] Certify Public Key <> User ID binding (aka Certification Signatures)
- [x] Binary Documents
- ASCII Armor: parse and create ASCII armored PGP messages
# Coming Soon
The next phase of swift-pgp is to support formatting PGP encrypted messages. This will add support for parsing and creating structures like:
- [ ] Symmetric-Key Encrypted Session Keys
- [ ] Symmetrically Encrypted Data
# Installing
1. `git submodule init; git submodule add git@github.com:kryptco/swift-pgp
2. Drag PGPFormat.xcodeproj/ to your project (don't check copy files, they're already there)
3. Add `CommonCrypto` to your project:
Go to Build Phases and add this `run script` phase:
```bash
modulesDirectory=$DERIVED_FILES_DIR/modules
modulesMap=$modulesDirectory/module.modulemap
modulesMapTemp=$modulesDirectory/module.modulemap.tmp
mkdir -p "$modulesDirectory"
cat > "$modulesMapTemp" << MAP
module CommonCrypto [system] {
header "$SDKROOT/usr/include/CommonCrypto/CommonCrypto.h"
export *
}
MAP
diff "$modulesMapTemp" "$modulesMap" >/dev/null 2>/dev/null
if [[ $? != 0 ]] ; then
mv "$modulesMapTemp" "$modulesMap"
else
rm "$modulesMapTemp"
fi
```

# How to use swift-pgp
Create signatures with swift-pgp by utilizing the `Signable` interface. The `Signable` interface is what makes the swift-pgp library public-key-cryptography-implementation-agnostic.
```swift
/**
Represents a structure that can be signed
*/
public protocol Signable {
var signature:Signature { get set }
func signableData() throws -> Data
}
```
The `Signable` interface is extended to provide two useful functions
- `func dataToHash() throws -> Data`
- `mutating func set(hash:Data, signedHash:Data) throws`
This lets you initialize a signable, extract the data that needs to be hashed via `dataToHash()`, hash it, sign it, and then set the hash and signature via `set(hash:Data, signedHash:Data)`. The `dataToHash()` function can also be used to extract the data that needs to be hashed to verify signatures.
Currently, there are only two types of Signables: `SignedPublicKeyIdentity` and `SignedBinaryDocument`.
# Examples
Below are a few examples for creating certification and binary document signatures.
## `SignedPublicKeyIdentity`
A Public Key <> User ID binding certification.
```swift
// initialize a public key
let publicKeyData = RSAPublicKey(modulus: ..., exponent: ...)
let publicKey = try PublicKey(create: .rsaSignOnly, publicKeyData: publicKeyData, date: Date())
// initialize a user id
let userID = UserID(name: "Alex Grinman", email: "hello@krypt.co")
// initialize the signed public key
var signedPublicKey = try SignedPublicKeyIdentity(publicKey: publicKey, userID: userID, hashAlgorithm: .sha512)
// extract the data to hash and sign, sign it, and set it on the signedPublicKey
let dataToHash = try signedPublicKey.dataToHash()
let hash = H(dataToHash) // where H is your chosen (i.e. sha512) hash implementation
let signatureData = X(dataToHash) // where X is your chosen RSA sign implementation
try signedPublicKey.set(hash: hash, signedHash: signatureData)
// get the ASCII armored message
let asciiMessage = try signedPublicKey.armoredMessage(blockType: .publicKey, comment: "created with swift-pgp")
```
> **Multiple UserIDs** often certifications need to say that several User IDs are binded to a public key. swift-pgp provides a helper struct for this called `SignedPublicKeyIdentities` that is initialized with an list of `SignedPublicKeyIdentity`s.
## `SignedBinaryDocument`
A signature for a binary document.
```swift
// the bytes of the document being signed, i.e. 0xDEADBEEF
let binaryData = Data(bytes: [0xDE, 0xAD, 0xBE, 0xEF])
var signedBinary = SignedBinaryDocument(binary: binaryData, publicKeyAlgorithm: .rsaSignOnly, hashAlgorithm: .sha512)
// extract the data to hash and sign, sign it, and set it on the signedPublicKey
let dataToHash = try signedBinary.dataToHash()
let hash = H(dataToHash) // where H is your chosen (i.e. sha512) hash implementation
let signatureData = X(dataToHash) // where X is your chosen RSA sign implementation
// compile the signed public key packets
try signedBinary.set(hash: hash, signedHash: signatureData)
// return ascii armored signature
let asciiMessage = try signedBinary.set(blockType: .signature, comment: "created with swift-pgp")
```
# License
We are currently deciding on a license for swift-pgp.
For now, the code is released under All Rights Reserved.