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

Add Elliptic Curve variants for JWS and JWK utilities #88

Merged
22 commits merged into from
Jan 21, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
4373b64
Add EC variants for JWS and JWK
jarrodmoldrich Jul 3, 2018
f1924ee
Use raw signatures for EC, clarify variable names
jarrodmoldrich Jul 6, 2018
21ac3f8
Revert local project changes
jarrodmoldrich Jul 6, 2018
169f1b5
Implement feedback from Carol
jarrodmoldrich Jul 13, 2018
b47545e
Fix typo in 'compressedCurvePointsUnsupported'
jarrodmoldrich Jul 13, 2018
63eeac1
Reuse constants inside enum functions
jarrodmoldrich Jul 13, 2018
62ecef5
Add EC test primitives
jarrodmoldrich Oct 7, 2018
79f110e
Refactor test data into generic structure
jarrodmoldrich Oct 14, 2018
d5dad8a
Add openssl reference keys
jarrodmoldrich Oct 15, 2018
67e414a
Add EC signer tests
jarrodmoldrich Oct 27, 2018
1ae649b
Add EC key data component tests
jarrodmoldrich Oct 27, 2018
ab5787e
Add public key conversion tests
jarrodmoldrich Oct 27, 2018
013cf5f
Add more EC key conversion tests
jarrodmoldrich Oct 27, 2018
496474f
Add EC JWS tests
jarrodmoldrich Jan 9, 2019
e69fed5
Add EC JWK tests
jarrodmoldrich Jan 9, 2019
87a24c1
Replace re-used test array with common instance
jarrodmoldrich Jan 10, 2019
008d3d3
Add missing unhappy path tests
jarrodmoldrich Jan 10, 2019
2f41a4c
Add private key conversion features with test, fix conversion bug
jarrodmoldrich Jan 10, 2019
db946d2
Update feature support in README
jarrodmoldrich Jan 10, 2019
cc14e85
Merge remote-tracking branch 'origin/master' into add_ec_variants
jarrodmoldrich Jan 10, 2019
e8cef12
Use internal common crypto
jarrodmoldrich Jan 10, 2019
4050684
Implement review suggestions
jarrodmoldrich Jan 19, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add EC test primitives
  • Loading branch information
jarrodmoldrich committed Oct 7, 2018
commit 62ecef5ec078bfcf69fcd7ce7eaf3ef35df6ffa8
12 changes: 12 additions & 0 deletions JOSESwift.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
5FB763AFF6BE04E8A6AE4DFC /* DataECPublicKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FB763EED5A790CCC29F8771 /* DataECPublicKey.swift */; };
5FB764055756A9190628BDDE /* ECKeyCodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FB76EBD36093E9EC475BC2B /* ECKeyCodable.swift */; };
5FB7641E9D67F245F52F3A7E /* EC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FB760DB390F90F91102DB74 /* EC.swift */; };
5FB76902DBBBEBE867D17D94 /* RSACryptoTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FB7683476B521915FDB2248 /* RSACryptoTestCase.swift */; };
5FB76AC31C9A627FB8626CF3 /* ECVerifierTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FB768A267E1A15571CC58AA /* ECVerifierTests.swift */; };
5FB76B8D7F1214FF01FA1A8B /* ECVerifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FB767ECBB50E5A47C671DC1 /* ECVerifier.swift */; };
5FB76E6F2080BEC6B63939D6 /* ECSigner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FB76AF2833DDD77D56D6D3F /* ECSigner.swift */; };
5FB76E7BEF001684139C9E14 /* ECCryptoTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FB76BD4F46045BF2B182483 /* ECCryptoTestCase.swift */; };
6505236E1FB4940100E0B1B1 /* AESEncrypter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6505236D1FB4940100E0B1B1 /* AESEncrypter.swift */; };
650523701FB494BE00E0B1B1 /* AESDecrypter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6505236F1FB494BE00E0B1B1 /* AESDecrypter.swift */; };
65125A321FBF85FA007CF3AE /* JWSDeserializationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65125A311FBF85FA007CF3AE /* JWSDeserializationTests.swift */; };
Expand Down Expand Up @@ -107,8 +110,11 @@
5FB760DB390F90F91102DB74 /* EC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EC.swift; sourceTree = "<group>"; };
5FB763EED5A790CCC29F8771 /* DataECPublicKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataECPublicKey.swift; sourceTree = "<group>"; };
5FB767ECBB50E5A47C671DC1 /* ECVerifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ECVerifier.swift; sourceTree = "<group>"; };
5FB7683476B521915FDB2248 /* RSACryptoTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RSACryptoTestCase.swift; sourceTree = "<group>"; };
5FB768A267E1A15571CC58AA /* ECVerifierTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ECVerifierTests.swift; sourceTree = "<group>"; };
5FB76A41AECF99F3673C1C40 /* ECKeys.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ECKeys.swift; sourceTree = "<group>"; };
5FB76AF2833DDD77D56D6D3F /* ECSigner.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ECSigner.swift; sourceTree = "<group>"; };
5FB76BD4F46045BF2B182483 /* ECCryptoTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ECCryptoTestCase.swift; sourceTree = "<group>"; };
5FB76CEA2BD69C2AF38D2AFC /* SecKeyECPublicKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecKeyECPublicKey.swift; sourceTree = "<group>"; };
5FB76EBD36093E9EC475BC2B /* ECKeyCodable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ECKeyCodable.swift; sourceTree = "<group>"; };
6505236D1FB4940100E0B1B1 /* AESEncrypter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AESEncrypter.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -250,6 +256,9 @@
C8EE14531FAC797500A616E4 /* RSAVerifierTests.swift */,
C8F0964F1FC56B25000BEE4D /* RSAEncrypterTests.swift */,
C8A5923F1FC71586009CEFA6 /* RSADecrypterTests.swift */,
5FB7683476B521915FDB2248 /* RSACryptoTestCase.swift */,
5FB76BD4F46045BF2B182483 /* ECCryptoTestCase.swift */,
5FB768A267E1A15571CC58AA /* ECVerifierTests.swift */,
);
name = Crypto;
sourceTree = "<group>";
Expand Down Expand Up @@ -633,6 +642,9 @@
C8EE14541FAC797500A616E4 /* RSAVerifierTests.swift in Sources */,
658261492029E2D200B594ED /* SecKeyRSAPublicKeyTests.swift in Sources */,
C86AC8CB1FCEC20F0007E611 /* AESEncrypterTests.swift in Sources */,
5FB76E7BEF001684139C9E14 /* ECCryptoTestCase.swift in Sources */,
5FB76902DBBBEBE867D17D94 /* RSACryptoTestCase.swift in Sources */,
5FB76AC31C9A627FB8626CF3 /* ECVerifierTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
2 changes: 1 addition & 1 deletion Tests/AESDecrypterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import XCTest
@testable import JOSESwift
import SJCommonCrypto

class AESDecrypterTests: CryptoTestCase {
class AESDecrypterTests: RSACryptoTestCase {

override func setUp() {
super.setUp()
Expand Down
2 changes: 1 addition & 1 deletion Tests/AESEncrypterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import XCTest
@testable import JOSESwift
import SJCommonCrypto

class AESEncrypterTests: CryptoTestCase {
class AESEncrypterTests: RSACryptoTestCase {

override func setUp() {
super.setUp()
Expand Down
126 changes: 4 additions & 122 deletions Tests/CryptoTestCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,102 +25,6 @@ import XCTest

class CryptoTestCase: XCTestCase {
let message = "The true sign of intelligence is not knowledge but imagination."
let privateKey2048Tag = "com.airsidemobile.JOSESwift.testPrivateKey2048"
let privateKey4096Tag = "com.airsidemobile.JOSESwift.testPrivateKey4096"

var privateKey2048: SecKey?
var publicKey2048: SecKey?

var privateKey4096: SecKey?
var publicKey4096: SecKey?

let compactSerializedJWSRS512Const = """
eyJhbGciOiJSUzUxMiJ9.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.dar4u\
Qfhg7HpAXDrFJEP3T6cPePUIstu3tCLiz-HBEx1yAQXxLweQrKOYvIWOlt_HfxjjhxfGDoSXjnQMVHZTJaAYFNtK382pfOKpJAxE6UvkhLtvS-A\
6BKLWMS_aUVgqizOIXH0IeuVz1COpSLlsQ5KICUaqsxYyPfD28vbbQ9IfJ4RyJmSqEEx-M8BY2r4v_HHL-kyvjqGbSoF7o9Z6Cg1CetPJ5OHPBM\
XZa_Aj3LkNWn1GSw5B4WQueb8E0uJVAzLSNbxA-ZNowlOgDtKHOEkwbZu6zj7WvLEm8xovgmAha_y7HssoXnH26Nu-8RMUYw-LXUJz6Fny1F_xc\
v_TA
"""

let compactSerializedJWSRS256Const = """
eyJhbGciOiJSUzI1NiJ9.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.Cx2UI\
OKzA8O2PJXn4JJLnPTky0lI43hfXyZsRYpVSj_qR36aYEyuofoLH_RlF2IDiU_-ih7wdu83w45-iP_vneADXKHBA3yChB3DSjEWj7ocjgTp5xzB\
ZrWKXH3tTleuaWr2jKkAXyGtosvDgd828fxEnH-lVpzMfyoqMyOw1YJFi-2GuPzslKZ5OsP09zBydxQ5jjggQVnEJQGb4JTzhnI9Z10CBBJt5rz\
RyZSHUzf3nVq4HY36GWUPMQPNEFtaCcK_qgBB3KilffHFMNGBIgds6qkbT53Bml9AqB1xdJMBOtF2hdccQjRpZIT5aDUlHIwILXWG91ytpDrBpX\
ky8g
"""

var publicKey2048Data: Data!
var publicKey4096Data: Data!

// Generated by OpenSSL for `publicKey` (without leading 0x00).
let expectedModulus2048Base64 = """
iADzxMJ-l_NIVPbqz9eoBenUCCUiNNfZ37c6gUJwWEfJRyGchAe96m4GLr3pzj2A3Io4MSKf9dDWMak6qkR_XYljSjZBbXAhQan2sIB5qyPW7NJ\
7XpJWHoaHdHwEN9Cj29zL-WtFk6lC1rPDmNPRTmRy0ct4EP4YJ49PMcoKJQKbog79ws1KdDzNGTVVkEgLB4VOlW8A164kaK8-xMUxTqySUtigLT\
DUMqjQ_81SFgsNnMUqnxp87bKD77olYBia88r8V2YXEx1Jgl8t22gNNh6lkN8BDqlkb_Y2uS-c7vlYIfSH6WYkVsSPsrA-GLLRo_R07FGxvs2M5\
gZxnmlvew
"""

// Generated by OpenSSL for `publicKey4096` (without leading 0x00).
let expectedModulus4096Base64 = """
v-rKTWfCkZmUjQsppCM7u3DVz2bYaoFp_c5r4lwLJXvP9S99dAVMG5YHiJAHVLSMDIm0O5WTNR_1pvwPA57zal2Gss9q-a4imx-f5pyC8e2vtro\
zS3hejcZyYSSdotJCSfGWaSh1_8CyIyrAoMfHLt4-YHH7U6N1h7nqIzt5thybBObsBkTiul5hMqxf02SEqxZpPfv0AKMKPontcxuO1DRgQUkcPk\
ljKSysurNwmET3Dl50NkuYhCsUe5mz5yu9GHT6HER-47helljRF4d1d4RTkzk1BnXy1ZbmsdTN9vewmYuAqACLAVdPiK4ejw46l8aSOclazireR\
Q04ismklfP1wc3CJ532CZ4PKf0tfflOmhEAXyjF3VwQsj0yl_4S5JphoutWkq_hN1AVX6K3F9xEENm4dddaetFYWgQpjjth8UwM_Svm7aflR9f-\
g_1xjxvaPAG-ir-NqIsFeVpk8OJ-ZKg1YMKmYIcyRptnn1XNdJz5724r1xge_oPzfFxYqGEeAmRhPaB5HgvS8ysF0YhtskJFGsB6P3DxFm-1RgU\
g2IlwBa-8gGvkwZ5W0Hy1gyZo-BZVHG2G-un2nJd_t4L-io1bgBG3sE-vOmV98L6tTzlKdyroa9xi45QRiN0SzA0an0x1fdJzSkh-FcVIQ0ELDJ\
DgruI_mX4M_u3yazs
"""

// Generated by OpenSSL for `publicKey`.
let expectedExponentBase64 = "AQAB"

// Dummy data since we don't (yet) implement any `ExpressibleAsRSAPrivateKeyComponents`.
let expectedPrivateExponentBase64 = "MHZ4Li4uS2d3"

// Generated by OpenSSL for `publicKey` (without leading 0x00).
let expectedModulus2048Data = Data(bytes: [
136, 0, 243, 196, 194, 126, 151, 243, 72, 84, 246, 234, 207, 215, 168, 5, 233, 212, 8, 37, 34, 52, 215, 217,
223, 183, 58, 129, 66, 112, 88, 71, 201, 71, 33, 156, 132, 7, 189, 234, 110, 6, 46, 189, 233, 206, 61, 128, 220,
138, 56, 49, 34, 159, 245, 208, 214, 49, 169, 58, 170, 68, 127, 93, 137, 99, 74, 54, 65, 109, 112, 33, 65, 169,
246, 176, 128, 121, 171, 35, 214, 236, 210, 123, 94, 146, 86, 30, 134, 135, 116, 124, 4, 55, 208, 163, 219, 220,
203, 249, 107, 69, 147, 169, 66, 214, 179, 195, 152, 211, 209, 78, 100, 114, 209, 203, 120, 16, 254, 24, 39,
143, 79, 49, 202, 10, 37, 2, 155, 162, 14, 253, 194, 205, 74, 116, 60, 205, 25, 53, 85, 144, 72, 11, 7, 133, 78,
149, 111, 0, 215, 174, 36, 104, 175, 62, 196, 197, 49, 78, 172, 146, 82, 216, 160, 45, 48, 212, 50, 168, 208,
255, 205, 82, 22, 11, 13, 156, 197, 42, 159, 26, 124, 237, 178, 131, 239, 186, 37, 96, 24, 154, 243, 202, 252,
87, 102, 23, 19, 29, 73, 130, 95, 45, 219, 104, 13, 54, 30, 165, 144, 223, 1, 14, 169, 100, 111, 246, 54, 185,
47, 156, 238, 249, 88, 33, 244, 135, 233, 102, 36, 86, 196, 143, 178, 176, 62, 24, 178, 209, 163, 244, 116, 236,
81, 177, 190, 205, 140, 230, 6, 113, 158, 105, 111, 123
])

// Generated by OpenSSL for `publicKey4096` (without leading 0x00).
let expectedModulus4096Data = Data(bytes: [
191, 234, 202, 77, 103, 194, 145, 153, 148, 141, 11, 41, 164, 35, 59, 187, 112, 213, 207, 102, 216, 106, 129,
105, 253, 206, 107, 226, 92, 11, 37, 123, 207, 245, 47, 125, 116, 5, 76, 27, 150, 7, 136, 144, 7, 84, 180, 140,
12, 137, 180, 59, 149, 147, 53, 31, 245, 166, 252, 15, 3, 158, 243, 106, 93, 134, 178, 207, 106, 249, 174, 34,
155, 31, 159, 230, 156, 130, 241, 237, 175, 182, 186, 51, 75, 120, 94, 141, 198, 114, 97, 36, 157, 162, 210, 66,
73, 241, 150, 105, 40, 117, 255, 192, 178, 35, 42, 192, 160, 199, 199, 46, 222, 62, 96, 113, 251, 83, 163, 117,
135, 185, 234, 35, 59, 121, 182, 28, 155, 4, 230, 236, 6, 68, 226, 186, 94, 97, 50, 172, 95, 211, 100, 132, 171,
22, 105, 61, 251, 244, 0, 163, 10, 62, 137, 237, 115, 27, 142, 212, 52, 96, 65, 73, 28, 62, 73, 99, 41, 44, 172,
186, 179, 112, 152, 68, 247, 14, 94, 116, 54, 75, 152, 132, 43, 20, 123, 153, 179, 231, 43, 189, 24, 116, 250,
28, 68, 126, 227, 184, 94, 150, 88, 209, 23, 135, 117, 119, 132, 83, 147, 57, 53, 6, 117, 242, 213, 150, 230,
177, 212, 205, 246, 247, 176, 153, 139, 128, 168, 0, 139, 1, 87, 79, 136, 174, 30, 143, 14, 58, 151, 198, 146,
57, 201, 90, 206, 42, 222, 69, 13, 56, 138, 201, 164, 149, 243, 245, 193, 205, 194, 39, 157, 246, 9, 158, 15,
41, 253, 45, 125, 249, 78, 154, 17, 0, 95, 40, 197, 221, 92, 16, 178, 61, 50, 151, 254, 18, 228, 154, 97, 162,
235, 86, 146, 175, 225, 55, 80, 21, 95, 162, 183, 23, 220, 68, 16, 217, 184, 117, 215, 90, 122, 209, 88, 90, 4,
41, 142, 59, 97, 241, 76, 12, 253, 43, 230, 237, 167, 229, 71, 215, 254, 131, 253, 113, 143, 27, 218, 60, 1,
190, 138, 191, 141, 168, 139, 5, 121, 90, 100, 240, 226, 126, 100, 168, 53, 96, 194, 166, 96, 135, 50, 70, 155,
103, 159, 85, 205, 116, 156, 249, 239, 110, 43, 215, 24, 30, 254, 131, 243, 124, 92, 88, 168, 97, 30, 2, 100,
97, 61, 160, 121, 30, 11, 210, 243, 43, 5, 209, 136, 109, 178, 66, 69, 26, 192, 122, 63, 112, 241, 22, 111, 181,
70, 5, 32, 216, 137, 112, 5, 175, 188, 128, 107, 228, 193, 158, 86, 208, 124, 181, 131, 38, 104, 248, 22, 85,
28, 109, 134, 250, 233, 246, 156, 151, 127, 183, 130, 254, 138, 141, 91, 128, 17, 183, 176, 79, 175, 58, 101,
125, 240, 190, 173, 79, 57, 74, 119, 42, 232, 107, 220, 98, 227, 148, 17, 136, 221, 18, 204, 13, 26, 159, 76,
117, 125, 210, 115, 74, 72, 126, 21, 197, 72, 67, 65, 11, 12, 144, 224, 174, 226, 63, 153, 126, 12, 254, 237,
242, 107, 59
])

// Generated by OpenSSL for `publicKey`.
let expectedExponentData = Data(bytes: [ 1, 0, 1 ])

override func setUp() {
super.setUp()
Expand All @@ -131,35 +35,13 @@ class CryptoTestCase: XCTestCase {
super.tearDown()
}

private func setupKeys() {
if
let path = Bundle(for: type(of: self)).path(forResource: "TestKey", ofType: "plist"),
let keyDict = NSDictionary(contentsOfFile: path),
let keyData2048 = Data(base64Encoded: keyDict[privateKey2048Tag] as! String),
let keyData4096 = Data(base64Encoded: keyDict[privateKey4096Tag] as! String)
{

// 2048

let keyPair2048 = setupSecKeyPair(size: 2048, data: keyData2048, tag: privateKey2048Tag)!

privateKey2048 = keyPair2048.privateKey
publicKey2048 = keyPair2048.publicKey
publicKey2048Data = SecKeyCopyExternalRepresentation(publicKey2048!, nil)! as Data

// 4096

let keyPair4096 = setupSecKeyPair(size: 4096, data: keyData4096, tag: privateKey4096Tag)!

privateKey4096 = keyPair4096.privateKey
publicKey4096 = keyPair4096.publicKey
publicKey4096Data = SecKeyCopyExternalRepresentation(publicKey4096!, nil)! as Data
}
public func setupKeys() {
XCTFail("Setup keys function is missing")
}

private func setupSecKeyPair(size: Int, data: Data, tag: String) -> (privateKey: SecKey, publicKey: SecKey)? {
func setupSecKeyPair(type: String, size: Int, data: Data, tag: String) -> (privateKey: SecKey, publicKey: SecKey)? {
let attributes: [String: Any] = [
kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
kSecAttrKeyType as String: type,
kSecAttrKeyClass as String: kSecAttrKeyClassPrivate,
kSecAttrKeySizeInBits as String: size,
kSecPrivateKeyAttrs as String: [
Expand Down
2 changes: 1 addition & 1 deletion Tests/DataRSAPublicKeyTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import XCTest
@testable import JOSESwift

class DataRSAPublicKeyTests: CryptoTestCase {
class DataRSAPublicKeyTests: RSACryptoTestCase {

func testLeadingZeroDropped() {
let components = try! publicKey2048Data.rsaPublicKeyComponents()
Expand Down
Loading