Skip to content

Commit

Permalink
Merge pull request #981 from btoms20/dev/rsa-api
Browse files Browse the repository at this point in the history
Updated RSA Public API
  • Loading branch information
nathanfallet authored Sep 17, 2022
2 parents bee7ed5 + 713f0e0 commit caf228a
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 47 deletions.
57 changes: 11 additions & 46 deletions Sources/CryptoSwift/PEM/DER.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,81 +21,46 @@ internal protocol DERCodable: DERDecodable, DEREncodable { }
/// Conform to this protocol if your type can be instantiated from a ASN1 DER representation
internal protocol DERDecodable {
/// Attempts to instantiate an instance of your Public Key when given a DER representation of your Public Key
///
/// - Parameter publicDER: The ASN.1 DER representation of your Public Key
init(publicDER: Array<UInt8>) throws

/// Attempts to instantiate an instance of your Private Key when given a DER representation of your Private Key
///
/// - Parameter privateDER: The ASN.1 DER representation of your Private Key
init(privateDER: Array<UInt8>) throws

/// Attempts to instantiate a Key when given the ASN1 DER encoded external representation of the Key
///
/// An example of importing a SecKey RSA key (from Apple's `Security` framework) for use within CryptoSwift
/// ```
/// /// Starting with a SecKey RSA Key
/// let rsaSecKey:SecKey
///
/// /// Copy the External Representation
/// var externalRepError:Unmanaged<CFError>?
/// guard let externalRep = SecKeyCopyExternalRepresentation(rsaSecKey, &externalRepError) as? Data else {
/// /// Failed to copy external representation for RSA SecKey
/// return
/// }
///
/// /// Instantiate the RSA Key from the raw external representation
/// let rsaKey = try RSA(rawRepresentation: externalRep)
///
/// /// You now have a CryptoSwift RSA Key
/// // rsaKey.encrypt(...)
/// // rsaKey.decrypt(...)
/// // rsaKey.sign(...)
/// // rsaKey.verify(...)
/// ```
/// - Parameter rawRepresentation: The ASN1 DER Encoded external representation (either public or private)
/// - Note: The external representation is identical to that of `SecKeyCopyExternalRepresentation` function from Apple's `Security` framework
init(rawRepresentation: Data) throws
}

extension DERDecodable {
public init(rawRepresentation raw: Data) throws {
/// The default implementation that makes the original internal initializer publicly available
do { try self.init(privateDER: raw.bytes) } catch {
try self.init(publicDER: raw.bytes)
}
}
}

/// Conform to this protocol if your type can be described in an ASN1 DER representation
internal protocol DEREncodable {
/// Returns the DER encoded representation of the Public Key
func publicKeyDER() throws -> Array<UInt8>

/// Returns the DER encoded representation of the Private Key
func privateKeyDER() throws -> Array<UInt8>

/// A semantically similar function that mimics the `SecKeyCopyExternalRepresentation` function from Apple's `Security` framework
/// - Note: If called on a Private Key, this method will return the Private Keys DER Representation. Likewise, if called on a Public Key, this method will return the Public Keys DER Representation
/// - Note: If you'd like to export the Public Keys DER from a Private Key, use the `publicKeyExternalRepresentation()` function
func externalRepresentation() throws -> Data

/// A semantically similar function that mimics the `SecKeyCopyExternalRepresentation` function from Apple's `Security` framework
/// - Note: This function only ever exports the Public Key's DER representation. If called on a Private Key, the corresponding Public Key will be extracted and exported.
func publicKeyExternalRepresentation() throws -> Data
}

extension DEREncodable {
public func externalRepresentation() throws -> Data {
// The default implementation that makes the original internal function publicly available
do { return try Data(self.privateKeyDER()) } catch {
return try Data(self.publicKeyDER())
}
}

public func publicKeyExternalRepresentation() throws -> Data {
// The default implementation that makes the original internal function publicly available
try Data(self.publicKeyDER())
}
}

struct DER {
internal enum Error:Swift.Error {
internal enum Error: Swift.Error {
/// We were provided invalid DER data
case invalidDERFormat
}

/// Integer to Octet String Primitive
/// - Parameters:
/// - x: nonnegative integer to be converted
Expand Down
35 changes: 34 additions & 1 deletion Sources/CryptoSwift/RSA/RSA.swift
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,35 @@ extension RSA {
// Proceed with regular initialization
self.init(n: BigUInteger(modulus), e: BigUInteger(publicExponent), d: BigUInteger(privateExponent), p: BigUInteger(prime1), q: BigUInteger(prime2))
}

/// Attempts to instantiate an RSA Key when given the ASN1 DER encoded external representation of the Key
///
/// An example of importing a SecKey RSA key (from Apple's `Security` framework) for use within CryptoSwift
/// ```
/// /// Starting with a SecKey RSA Key
/// let rsaSecKey:SecKey
///
/// /// Copy the External Representation
/// var externalRepError:Unmanaged<CFError>?
/// guard let externalRep = SecKeyCopyExternalRepresentation(rsaSecKey, &externalRepError) as? Data else {
/// /// Failed to copy external representation for RSA SecKey
/// return
/// }
///
/// /// Instantiate the RSA Key from the raw external representation
/// let rsaKey = try RSA(rawRepresentation: externalRep)
///
/// /// You now have a CryptoSwift RSA Key
/// // rsaKey.encrypt(...)
/// // rsaKey.decrypt(...)
/// // rsaKey.sign(...)
/// // rsaKey.verify(...)
/// ```
public convenience init(rawRepresentation raw: Data) throws {
do { try self.init(privateDER: raw.bytes) } catch {
try self.init(publicDER: raw.bytes)
}
}
}

// MARK: DER Exports (See #892)
Expand Down Expand Up @@ -352,13 +381,17 @@ extension RSA {
/// /// You now have a CryptoSwift RSA Key
/// ```
///
func externalRepresentation() throws -> Data {
public func externalRepresentation() throws -> Data {
if self.primes != nil {
return try Data(self.privateKeyDER())
} else {
return try Data(self.publicKeyDER())
}
}

public func publicKeyExternalRepresentation() throws -> Data {
return try Data(self.publicKeyDER())
}
}

// MARK: CS.BigUInt extension
Expand Down

0 comments on commit caf228a

Please sign in to comment.