Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added JWK and JWKS support #97

Merged
merged 15 commits into from Oct 23, 2019
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -5,4 +5,5 @@ Packages
Package.pins
Package.resolved
DerivedData
.swiftpm

27 changes: 15 additions & 12 deletions Package.swift
@@ -1,20 +1,23 @@
// swift-tools-version:4.0
// swift-tools-version:5.0
import PackageDescription

let package = Package(
name: "JWT",
name: "jwt-kit",
products: [
.library(name: "JWT", targets: ["JWT"]),
],
dependencies: [
// 🌎 Utility package containing tools for byte manipulation, Codable, OS APIs, and debugging.
.package(url: "https://github.com/vapor/core.git", from: "3.0.0"),

// 🔑 Hashing (BCrypt, SHA, HMAC, etc), encryption, and randomness.
.package(url: "https://github.com/vapor/crypto.git", from: "3.0.0"),
.library(name: "JWTKit", targets: ["JWTKit"]),
],
dependencies: [ ],
targets: [
.target(name: "JWT", dependencies: ["Core", "Crypto"]),
.testTarget(name: "JWTTests", dependencies: ["JWT"]),
.systemLibrary(
name: "CJWTKitOpenSSL",
pkgConfig: "openssl",
providers: [
.apt(["openssl libssl-dev"]),
.brew(["openssl"])
]
),
.target(name: "CJWTKitCrypto", dependencies: ["CJWTKitOpenSSL"]),
.target(name: "JWTKit", dependencies: ["CJWTKitCrypto"]),
.testTarget(name: "JWTKitTests", dependencies: ["JWTKit"]),
]
)
12 changes: 6 additions & 6 deletions README.md
@@ -1,21 +1,21 @@
<p align="center">
<img src="https://user-images.githubusercontent.com/1342803/36768561-e10bba90-1c0d-11e8-85b5-f9d1e605cc8a.png" height="64" alt="JWT">
<img src="https://user-images.githubusercontent.com/1342803/59471117-1c77b300-8e08-11e9-838e-441b280855b3.png" alt="JWTKit">
<br>
<br>
<a href="https://docs.vapor.codes/3.0/jwt/getting-started/">
<img src="http://img.shields.io/badge/read_the-docs-2196f3.svg" alt="Documentation">
<a href="https://api.vapor.codes/jwt-kit/master/JWTKit/index.html">
<img src="http://img.shields.io/badge/api-docs-2196f3.svg" alt="Documentation">
</a>
<a href="https://discord.gg/vapor">
<img src="https://img.shields.io/discord/431917998102675485.svg" alt="Team Chat">
</a>
<a href="LICENSE">
<img src="http://img.shields.io/badge/license-MIT-brightgreen.svg" alt="MIT License">
</a>
<a href="https://circleci.com/gh/vapor/jwt">
<img src="https://circleci.com/gh/vapor/jwt.svg?style=shield" alt="Continuous Integration">
<a href="https://circleci.com/gh/vapor/jwt-kit">
<img src="https://circleci.com/gh/vapor/jwt-kit.svg?style=shield" alt="Continuous Integration">
</a>
<a href="https://swift.org">
<img src="http://img.shields.io/badge/swift-4.1-brightgreen.svg" alt="Swift 4.1">
<img src="http://img.shields.io/badge/swift-5.0-brightgreen.svg" alt="Swift 5.0">
</a>
</p>

Expand Down
30 changes: 30 additions & 0 deletions Sources/CJWTKitCrypto/c_jwtkit_crypto.c
@@ -0,0 +1,30 @@
#include "include/c_jwtkit_crypto.h"

#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
EVP_MD_CTX *EVP_MD_CTX_new(void) {
return EVP_MD_CTX_create();
};

void EVP_MD_CTX_free(EVP_MD_CTX *ctx) {
EVP_MD_CTX_cleanup(ctx);
free(ctx);
};

int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) {
r->n = n;
r->e = e;
r->d = d;
return 0;
};

HMAC_CTX *HMAC_CTX_new(void) {
HMAC_CTX *ptr = malloc(sizeof(HMAC_CTX));
HMAC_CTX_init(ptr);
return ptr;
};

void HMAC_CTX_free(HMAC_CTX *ctx) {
HMAC_CTX_cleanup(ctx);
free(ctx);
};
#endif
25 changes: 25 additions & 0 deletions Sources/CJWTKitCrypto/include/c_jwtkit_crypto.h
@@ -0,0 +1,25 @@
#ifndef C_JWTKIT_OPENSSL_H
#define C_JWTKIT_OPENSSL_H

#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/sha.h>
#include <openssl/md5.h>
#include <openssl/hmac.h>
#include <openssl/rand.h>
#include <openssl/rsa.h>
#include <openssl/pkcs12.h>
#include <openssl/x509v3.h>

#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
EVP_MD_CTX *EVP_MD_CTX_new(void);
void EVP_MD_CTX_free(EVP_MD_CTX *ctx);
int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d);
HMAC_CTX *HMAC_CTX_new(void);
void HMAC_CTX_free(HMAC_CTX *ctx);
#endif

#endif
4 changes: 4 additions & 0 deletions Sources/CJWTKitOpenSSL/module.modulemap
@@ -0,0 +1,4 @@
module CJWTKitOpenSSL [system] {
link "ssl"
link "crypto"
}
15 changes: 0 additions & 15 deletions Sources/JWT/Deprecated.swift

This file was deleted.

1 change: 0 additions & 1 deletion Sources/JWT/Exports.swift

This file was deleted.

22 changes: 22 additions & 0 deletions Sources/JWT/JWK+KeyOperation.swift
@@ -0,0 +1,22 @@
import Foundation

public extension JWK {
public enum KeyOperation: String, Codable {
/// Compute digital signature or MAC.
case sign
/// Verify digital signature or MAC.
case verify
/// Encrypt content.
case encrypt
/// Decrypt content and validate decryption, if applicable.
case decrypt
/// Encrypt key.
case wrapKey
/// Decrypt key and validate decryption, if applicable.
case unwrapKey
/// Derive key.
case deriveKey
/// Derive bits not to be used as a key.
case deriveBits
}
}
42 changes: 42 additions & 0 deletions Sources/JWT/JWK+PublicKeyUse.swift
@@ -0,0 +1,42 @@
import Foundation

public extension JWK {
public enum PublicKeyUse: RawRepresentable, Codable {
case signature
case encryption
case other(String)

public var rawValue: String {
switch self {
case .signature:
return "sig"
case .encryption:
return "enc"
case .other(let value):
return value
}
}

public init(rawValue: String) {
switch rawValue {
case "sig":
self = .signature
case "enc":
self = .encryption
default:
self = .other(rawValue)
}
}

public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let rawValue = try container.decode(String.self)
self.init(rawValue: rawValue)
}

public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(self.rawValue)
}
}
}